ECON 494 - Spatial Data Science Project
Our project aimed to analyze the Ukraine conflict using spatial
analysis and maps generated through data from ACLED (Armed Conflict
Location & Event Data Project). Focusing on the violence targeting
civilians after invasion of Russia into Ukraine, we utilized R
programming to extract and visualize the conflict data, enabling us to
present a comprehensive overview of the events and their spatial
distribution.
library(sp)
library(raster)
library(ggplot2)
library(dplyr)
Attaching package: ‘dplyr’
The following objects are masked from ‘package:raster’:
intersect, select, union
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
library(tidyverse)
── Attaching core tidyverse packages ─────────────────────────────────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ forcats 1.0.0 ✔ stringr 1.5.0
✔ lubridate 1.9.2 ✔ tibble 3.2.1
✔ purrr 1.0.1 ✔ tidyr 1.3.0
✔ readr 2.1.4 ── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ tidyr::extract() masks raster::extract()
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
✖ dplyr::select() masks raster::select()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(conflicted)
Introduction
Russia invaded Ukraine in February 2022, resulting in the highest
levels of political violence recorded in a single country by
ACLED.
Civilians in Ukraine have faced shelling, indiscriminate strikes,
deliberate attacks, and harsh treatment in occupied areas.
Russian forces targeted Kyiv but retreated in northern Ukraine
while quickly seizing territories in southern and eastern
regions.
Over 5,000 reported civilian fatalities have occurred, but the
actual toll is likely much higher.
Different regions of Ukraine experienced varying levels of
violence and occupation during the conflict.
#ukraine_states_rds <- raster::getData('GADM', country = "UKR", level = 1)
ukraine_states_rds = readRDS("ukraine.rds") #https://gadm.org/download_country.html
ukraine_map <- ggplot() +
geom_polygon(data=ukraine_states_rds, aes(x = long, y = lat, group = group, fill = id), fill="orange", alpha = 0.6 ) + guides(fill = "none")
Regions defined for each Polygons
ukraine_map

east_ukraine_states_rds_names <- list("Dnipropetrovs'k", "Donets'k", "Luhans'k" , "Kharkiv", "Zaporizhzhya")
east_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% east_ukraine_states_rds_names)
south_ukraine_states_rds_names <- list("Chernihiv", "Kiev", "Kiev City", "Zhytomyr", "Sumy")
south_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% south_ukraine_states_rds_names)
central_ukraine_states_rds_names <- list("Cherkasy", "Kirovohrad", "Poltava", "Vinnytsya")
central_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% central_ukraine_states_rds_names)
western_ukraine_states_rds_names <- list("Volyn", "Chernivtsi", "Ivano-Frankivs'k", "Khmel'nyts'kyy", "Rivne", "L'viv", "Ternopil'", "Transcarpathia")
western_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% western_ukraine_states_rds_names)
southern_ukraine_states_rds_names <- list("Crimea", "Kherson", "Mykolayiv", "Odessa")
southern_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% southern_ukraine_states_rds_names)
ukraine_map2 <- ukraine_map +
geom_polygon(data=east_ukraine_states_rds, aes(x = long, y = lat, group = group), fill="red", alpha=0.2, color="black") +
geom_polygon(data=south_ukraine_states_rds, aes(x = long, y = lat, group = group), fill="black", alpha=0.2, color="black") +
geom_polygon(data=central_ukraine_states_rds, aes(x = long, y = lat, group = group), fill="darkblue", alpha=0.4, color="black") +
geom_polygon(data=western_ukraine_states_rds, aes(x = long, y = lat, group = group), fill="lightblue", alpha=0.2, color="black") +
geom_polygon(data=southern_ukraine_states_rds, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black")
Regions defined for each PolygonsRegions defined for each PolygonsRegions defined for each PolygonsRegions defined for each PolygonsRegions defined for each Polygons
ukraine_map2

centroid <- ukraine_states_rds$centroid <- coordinates(ukraine_states_rds)
ukraine_states_rds_names <- ukraine_states_rds$NAME_1
ukraine_map3 <- ukraine_map2 +
geom_text(aes(x = centroid[, 1], y = centroid[, 2], label = ukraine_states_rds_names), size=2) + labs(title = "Regions of Ukraine", fontface="bold") + theme_void() + theme(plot.title = element_text(hjust = 0.5, face = "bold")) + coord_map(projection = "albers", lat0 = 49, lat1 = 54)
ukraine_map3

Conflict Data (ACLED)
eastern_ukraine_states_names = list("Dnipropetrovsk", "Luhansk", "Donetsk", "Kharkiv", "Zaporizhia")
conflict <- read_csv('ukraine.csv', show_col_types = FALSE)
conflict$event_date <- as.Date(conflict$event_date, format = "%d %B %Y")
unique(conflict$admin1)
[1] "Dnipropetrovsk" "Luhansk" "Donetsk" "Kharkiv" "Kherson" "Sumy" "Zaporizhia"
[8] "Kyiv City" "Chernihiv" "Crimea" "Chernivtsi" "Ivano-Frankivsk" "Khmelnytskyi" "Lviv"
[15] "Mykolaiv" "Odesa" "Poltava" "Vinnytsia" "Kirovograd" "Zhytomyr" "Ternopil"
[22] "Cherkasy" "Kyiv" "Volyn" NA "Rivne" "Zakarpattia"
unique(conflict$event_type)
[1] "Explosions/Remote violence" "Battles" "Strategic developments" "Violence against civilians"
[5] "Protests" "Riots"
unique(conflict$sub_event_type)
[1] "Shelling/artillery/missile attack" "Armed clash" "Air/drone strike"
[4] "Remote explosive/landmine/IED" "Disrupted weapons use" "Other"
[7] "Agreement" "Attack" "Arrests"
[10] "Change to group/activity" "Looting/property destruction" "Non-state actor overtakes territory"
[13] "Abduction/forced disappearance" "Peaceful protest" "Protest with intervention"
[16] "Government regains territory" "Sexual violence" "Suicide bomb"
[19] "Grenade" "Non-violent transfer of territory" "Mob violence"
[22] "Excessive force against protesters" "Headquarters or base established" "Violent demonstration"
Apparent War Crimes in Northern Ukraine
In northern Ukraine, ACLED records over 400 incidents targeting
civilians, with a significant number occurring during the Russian
advance and subsequent occupation. Shelling, artillery, and missile
attacks were the most common types of violence, but direct attacks on
civilian populations resulted in the highest number of reported civilian
fatalities. Mass graves were discovered following the Russian retreat.
The Kyiv region, including the city of Kyiv, was most affected by these
strikes, while the Sumy region continued to suffer from strikes along
its border areas with Russia throughout the year. Incidents related to
accidental detonation of mines and explosives continued to occur during
and after the invasion. ACLED records at least 43 such events resulting
in at least 34 reported fatalities, with the highest incidence in April
and May 2022 in the Kyiv and Chernihiv regions following the Russian
withdrawal.
filtered_data <- conflict %>%
dplyr::filter(event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
civilian_targeting!="")
filtered_data <- filtered_data[filtered_data$admin1 %in% c("Zhytomyr", "Kyiv City", "Kyiv", "Sumy", "Chernihiv"),]
filtered_data$month_year <- format(filtered_data$event_date, "%B-%Y")
eastern <- filtered_data[filtered_data$admin1 %in% c("Dnipropetrovsk", "Donetsk", "Kharkiv", "Luhansk", "Zaporizhia"),]
eastern$month_year <- format(eastern$event_date, "%B-%Y")
# Create a new column called 'new_event_type'
filtered_data$new_event_type <- NA
# Map values based on 'sub_event_type'
filtered_data$new_event_type[filtered_data$sub_event_type %in% c("Remote explosive/landmine/IED", "Attack", "Air/drone strike", "Shelling/artillery/missile attack")] <- filtered_data$sub_event_type[filtered_data$sub_event_type %in% c("Remote explosive/landmine/IED", "Attack", "Air/drone strike", "Shelling/artillery/missile attack")]
filtered_data$new_event_type[!(filtered_data$sub_event_type %in% c("Remote explosive/landmine/IED", "Attack", "Air/drone strike", "Shelling/artillery/missile attack"))] <- "Other violence"
ggplot(filtered_data, aes(x = month_year, fill = new_event_type, )) +
geom_bar(position = "stack") +
labs(x = "Date", y = "Number of Events", title = "Violence Targeting Civilians in Northern Ukraine",
subtitle = "February 2022 - January 2023",
fill = "Sub-Event Type") +
theme_bw()

# Convert month_year column to proper date format
filtered_data$month_year <- as.Date(paste0("01-", filtered_data$month_year), format = "%d-%B-%Y")
# Sort the data by the month_year column
filtered_data <- filtered_data[order(filtered_data$month_year), ]
# Create the bar chart
ggplot(filtered_data, aes(x = month_year, fill = new_event_type, )) +
geom_bar(position = "stack") +
labs(x = "Date", y = "Number of Events", title = "Violence Targeting Civilians in Northern Ukraine",
subtitle = "February 2022 - January 2023",
fill = "Sub-Event Type") +
theme_bw()
# Convert month_year column to proper date format
eastern$month_year <- as.Date(paste0("01-", eastern$month_year), format = "%d-%B-%Y")
# Sort the data by the month_year column
eastern <- eastern[order(eastern$month_year), ]
# Create the bar chart
ggplot(eastern, aes(x = month_year, fill = admin1, )) +
geom_bar(position = "stack") +
labs(x = "Date", y = "Number of Events", title = "Violence Targeting Civilians in Eastern Ukraine",
subtitle = "February 2022 - January 2023",
fill = "Region") +
theme_bw()

Heavy Fighting Along the Frontline in Eastern Ukraine
Eastern Ukraine faces unprecedented violence, with three-quarters of
political violence events occurring in the region, primarily due to
shelling, artillery, and missile attacks. Despite relative distance from
the frontline, the Dnipropetrovsk region remains at risk, as Russia
continues air and missile strikes, exemplified by the deadly incident in
Dnipro on 14 January 2023.
Political Violence in Eastern Ukraine
Eastern parts of eastern Ukraine has been highly contested since the
beginning of the invasion. The eastern portion of the Kharkiv region,
which was occupied by Russian forces, served as a base for their
offensives in the Luhansk and Donetsk regions. The Luhansk region
experienced intense violence between late February and mid-summer 2022,
as Russian forces captured towns by destroying them with artillery. A
similar approach was employed in the spring of 2022 to capture Mariupol,
the last Ukrainian stronghold in the southern Donetsk region, resulting
in dire consequences for both trapped Ukrainian military personnel and
civilians. The Zaporizhia region experienced relatively lower levels of
armed violence due to Russia’s swift occupation in late February and
early March 2022.
conflict_eastern_ukraine <- conflict %>%
dplyr::filter(
event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
event_type %in% c("Explosions/Remote violence", "Battles", "Violence against civilians"),
admin1 %in% eastern_ukraine_states_names)
event_counts_eastern_ukraine <- conflict_eastern_ukraine %>%
group_by(longitude, latitude) %>%
reframe(number_of_events = n(), event_type)
east_ukraine_states_rds
class : SpatialPolygonsDataFrame
features : 5
extent : 32.96244, 40.21807, 46.07875, 50.46491 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
variables : 10
Warning: no non-missing arguments, returning NAWarning: no non-missing arguments, returning NAWarning: no non-missing arguments, returning NAWarning: no non-missing arguments, returning NA
names : GID_0, NAME_0, GID_1, NAME_1, VARNAME_1, NL_NAME_1, TYPE_1, ENGTYPE_1, CC_1, HASC_1
min values : UKR, Ukraine, UKR.15_1, Dnipropetrovs'k, Charkow|Jarkov|Karkov|Khar'kov, NA, Oblast', Region, NA, UA.DP
max values : UKR, Ukraine, UKR.8_1, Zaporizhzhya, Saporoshje|Zaporizhia|Zaporiz'ka Oblast'|Zaporojie|Zaporozhskaya Oblast'|Zaporozh'ye|Zaporožje, NA, Oblast', Region, NA, UA.ZP
eastern_ukraine_map <- ggplot() +
geom_polygon(data=east_ukraine_states_rds, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
eastern_ukraine_map

centroid <- east_ukraine_states_rds$centroid <- coordinates(east_ukraine_states_rds)
centroid[2] = centroid[2]+0.4
centroid[7] = centroid[7]-0.4
centroid[3] = centroid[3]-0.4
text <- geom_text(data = , aes(x = centroid[, 1], y = centroid[, 2], label = c("Dnipropetrovsk", "Donetsk", "Kharkiv", "Luhansk", "Zaporizhia")), color = "black", size = 4)
eastern_ukraine_map +
geom_point(data = event_counts_eastern_ukraine, aes(x = longitude, y = latitude, size = number_of_events, color=event_type)) +
geom_point(color="black", shape=21, data = event_counts_eastern_ukraine, aes(x = longitude, y = latitude, size = number_of_events, fill=event_type)) +
scale_size_continuous(range = c(0.1, 5)) +
labs(color = "Event Type", size = "Number of Events") +
labs(title = "Political Violence in Eastern Ukraine", fontface="bold") +
labs(subtitle = "February 2022 - January 2023 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5), plot.subtitle = element_text(hjust = 0.5)) +
text

Conflict in Kharkiv
Despite failing to break Ukrainian defenses in and around Kharkiv
city, Russian forces had taken control of the majority of the northern
and eastern parts of the region by April 2022, including the
strategically important transport hub of Izium. However, Ukraine managed
to liberate almost the entire region in an unexpected counter-offensive
in September 2022. Among the more than 800 incidents targeting
civilians, approximately three-quarters involved artillery, missiles,
and airstrikes, which also accounted for the majority of reported
civilian deaths in the region. Around one-third of these incidents
occurred in March 2022 alone.
conflict_kharkiv <- conflict %>%
dplyr::filter(
civilian_targeting != "",
event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
admin1 == "Kharkiv")
# Create a new column called 'new_event_type'
conflict_kharkiv$new_event_type <- NA
# Map values based on 'sub_event_type'
conflict_kharkiv$new_event_type[conflict_kharkiv$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Remote explosive/landmine/IED", "Attack")] <- conflict_kharkiv$sub_event_type[conflict_kharkiv$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Remote explosive/landmine/IED", "Attack")]
conflict_kharkiv$new_event_type[!(conflict_kharkiv$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Remote explosive/landmine/IED", "Attack"))] <- "Other violence"
number_of_events_kharkiv <- conflict_kharkiv %>%
group_by(longitude, latitude) %>%
reframe(number_of_events = n(), new_event_type)
kharkiv <- subset(ukraine_states_rds, NAME_1 == "Kharkiv")
kharkiv_map <- ggplot() +
geom_polygon(data=kharkiv, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
kharkiv_map

kharkiv_map +
geom_point(data = number_of_events_kharkiv, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
geom_point(color="black", shape=21, data = number_of_events_kharkiv, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
scale_size_continuous(range = c(0.1, 10)) +
labs(color = "Sub-Event Type", size = "Number of Events") +
labs(title = "Violence targeting Civilians in Kharkiv", fontface="bold") +
labs(subtitle = "February 2022 - January 2023 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Conflict in Luhansk
The extensive use of artillery, missiles, and airstrikes, along with
intense close combat, resulted in significant suffering for the civilian
population in the Luhansk region. Tragic incidents occurred, such as the
shelling of a nursing home in Kreminna on March 11, 2022, which
reportedly led to the death of 56 elderly patients. Additionally, an
airstrike on a school used as a shelter in Bilohorivka on May 7, 2022,
resulted in the loss of at least 60 lives. The shelling of Severodonetsk
in March and May 2022 also claimed the lives of over 50 civilians. After
the Russian occupation of the region in the summer of 2022, there was a
significant decrease in reports of civilians being targeted, although
the region has remained highly volatile, particularly since autumn.
conflict_luhansk <- conflict %>%
dplyr::filter(
civilian_targeting != "",
event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
admin1 == "Luhansk")
# Create a new column called 'new_event_type'
conflict_luhansk$new_event_type <- NA
# Map values based on 'sub_event_type'
conflict_luhansk$new_event_type[conflict_luhansk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Attack")] <- conflict_luhansk$sub_event_type[conflict_luhansk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Attack")]
conflict_luhansk$new_event_type[!(conflict_luhansk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Attack"))] <- "Other violence"
number_of_events_luhansk <- conflict_luhansk %>%
group_by(longitude, latitude) %>%
reframe(number_of_events = n(), new_event_type)
luhansk <- subset(ukraine_states_rds, NAME_1 == "Luhans'k")
luhansk_map <- ggplot() +
geom_polygon(data=luhansk, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
luhansk_map

luhansk_map +
geom_point(data = number_of_events_luhansk, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
geom_point(color="black", shape=21, data = number_of_events_luhansk, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
scale_size_continuous(range = c(0.1, 10)) +
labs(color = "Sub-Event Type", size = "Number of Events") +
labs(title = "Violence targeting Civilians in Luhansk", fontface="bold") +
labs(subtitle = "February 2022 - January 2023 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Conflict in Donetsk
ACLED data documents more than 16,000 incidents in the Donetsk
region, with over 12,000 of them involving shelling, artillery,
missiles, and airstrikes. Only a relatively small number of these
incidents, around 800, specifically targeted civilians. Prior to the
Russian occupation, the city of Mariupol witnessed multiple incidents
resulting in significant casualties. Mass casualty events caused by
long-range missile and artillery strikes were reported in various areas
of the region, affecting both sides of the line of contact.
conflict_donetsk <- conflict %>%
dplyr::filter(
civilian_targeting != "",
event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
admin1 == "Donetsk")
# Create a new column called 'new_event_type'
conflict_donetsk$new_event_type <- NA
# Map values based on 'sub_event_type'
conflict_donetsk$new_event_type[conflict_donetsk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")] <- conflict_donetsk$sub_event_type[conflict_donetsk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")]
conflict_donetsk$new_event_type[!(conflict_donetsk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED"))] <- "Other violence"
number_of_events_donetsk <- conflict_donetsk %>%
group_by(longitude, latitude) %>%
reframe(number_of_events = n(), new_event_type)
donetsk <- subset(ukraine_states_rds, NAME_1 == "Donets'k")
donetsk_map <- ggplot() +
geom_polygon(data=donetsk, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
donetsk_map

donetsk_map +
geom_point(data = number_of_events_donetsk, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
geom_point(color="black", shape=21, data = number_of_events_donetsk, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
scale_size_continuous(range = c(0.1, 10)) +
labs(color = "Sub-Event Type", size = "Number of Events") +
labs(title = "Violence targeting Civilians in Donetsk", fontface="bold") +
labs(subtitle = "February 2022 - January 2023 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Conflict in Zaporizhia
During the initial stages of the invasion, Russian forces
successfully occupied a significant portion of the Zaporizhia region.
This included the entire coastline of the Sea of Azov, encompassing the
Ukrainian navy base in Berdiansk, as well as an area extending from
Kherson to the southern Donetsk regions, reaching the Dnipro river. The
occupation also covered Melitopol, the region’s second-largest town.
Ukrainian forces managed to halt the advancement of Russian forces in
the Orikhiv and Huliaipole areas. While approximately half of the
incidents targeting civilians in the Zaporizhia region involved
shelling, air attacks, and drone strikes, civilians have also been
directly targeted. These attacks include firing at vehicles carrying
evacuating civilians, as well as instances of torture and execution. In
areas under Russian occupation, there are frequent reports of the
abduction of local officials, teachers, journalists, Ukrainian army
veterans, and civil activists.
conflict_zaporizhia <- conflict %>%
dplyr::filter(
civilian_targeting != "",
event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
admin1 == "Zaporizhia")
# Create a new column called 'new_event_type'
conflict_zaporizhia$new_event_type <- NA
# Map values based on 'sub_event_type'
conflict_zaporizhia$new_event_type[conflict_zaporizhia$sub_event_type %in% c("Attack", "Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")] <- conflict_zaporizhia$sub_event_type[conflict_zaporizhia$sub_event_type %in% c("Attack","Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")]
conflict_zaporizhia$new_event_type[!(conflict_zaporizhia$sub_event_type %in% c("Attack","Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED"))] <- "Other violence"
number_of_events_zaporizhia <- conflict_zaporizhia %>%
group_by(longitude, latitude) %>%
reframe(number_of_events = n(), new_event_type)
zaporizhia <- subset(ukraine_states_rds, NAME_1 == "Zaporizhzhya")
zaporizhia_map <- ggplot() +
geom_polygon(data=zaporizhia, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
zaporizhia_map

zaporizhia_map +
geom_point(data = number_of_events_zaporizhia, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
geom_point(color="black", shape=21, data = number_of_events_zaporizhia, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
scale_size_continuous(range = c(0.1, 10)) +
labs(color = "Sub-Event Type", size = "Number of Events") +
labs(title = "Violence targeting Civilians in Zaporizhia", fontface="bold") +
labs(subtitle = "February 2022 - January 2023 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Explosive Threats for Civilians in Southern Ukraine
Russian attempts for landings from the Black Sea were unsuccessful.
Russian forces invaded southern Ukraine from the annexed Crimean
peninsula, successfully overtaking the Kherson region and its main city
in March 2022. The Kherson and Mykolaiv regions experienced significant
violence, with artillery strikes leading to high fatality numbers. The
most common types of violence in Kherson were abductions, forced
disappearances, torture, targeting primarily officials, journalists,
activists, and those suspected of pro-Ukrainian views. In June 2022,
Russian forces reportedly abducted about 50 Crimean Tatars from Kherson.
Two significant incidents in the Odesa region include a missile strike
that killed 8 and injured 10 civilians on April 2022, and an airstrike
that killed at least 21 civilians on July 2022.
southern_ukraine_states_name = c("Mykolaiv", "Kherson", "Crimea", "Odesa" )
conflict_southern_ukraine <- conflict %>%
dplyr::filter(
civilian_targeting != "",
event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
admin1 %in% southern_ukraine_states_name)
# Create a new column called 'new_event_type'
conflict_southern_ukraine$new_event_type <- NA
# Map values based on 'sub_event_type'
conflict_southern_ukraine$new_event_type[conflict_southern_ukraine$sub_event_type %in% c("Attack", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")] <- conflict_southern_ukraine$sub_event_type[conflict_southern_ukraine$sub_event_type %in% c("Attack", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")]
conflict_southern_ukraine$new_event_type[!(conflict_southern_ukraine$sub_event_type %in% c("Attack", "Abduction/forced disappearance" , "Remote explosive/landmine/IED"))] <- "Other violence"
number_of_events_southern_ukraine <- conflict_southern_ukraine %>%
group_by(longitude, latitude) %>%
reframe(number_of_events = n(), new_event_type)
southern_ukraine <- subset(ukraine_states_rds, NAME_1 %in% southern_ukraine_states_rds_names)
southern_ukraine_map <- ggplot() +
geom_polygon(data=southern_ukraine, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
southern_ukraine_map

southern_ukraine_map +
geom_point(data = number_of_events_southern_ukraine, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
geom_point(color="black", shape=21, data = number_of_events_southern_ukraine, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
scale_size_continuous(range = c(0.1, 10)) +
labs(color = "Sub-Event Type", size = "Number of Events") +
labs(title = "Violence targeting Civilians in Southern Ukraine", fontface="bold") +
labs(subtitle = "February 2022 - January 2023 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Constant Menace from the Skies in Central and Western Ukraine
Over 150 Russian missile, air, and drone strikes have targeted the
Central and West regions, posing a significant threat to civilian
safety. Approximately one-fifth of these strikes hit civilian areas,
leading to over 80 fatalities. Two incidents accounted for most of the
reported fatalities: a missile strike on a shopping mall, in Poltava, on
June 2022, and a missile strike on a Vinnytsia concert hall on July
2022. At least 50 Russian strikes targeted energy infrastructure deep
within Ukraine which caused power outages, with Vinnytsia being one of
the most affected regions.
unique(conflict$admin1)
[1] "Dnipropetrovsk" "Luhansk" "Donetsk" "Kharkiv" "Kherson" "Sumy" "Zaporizhia"
[8] "Kyiv City" "Chernihiv" "Crimea" "Chernivtsi" "Ivano-Frankivsk" "Khmelnytskyi" "Lviv"
[15] "Mykolaiv" "Odesa" "Poltava" "Vinnytsia" "Kirovograd" "Zhytomyr" "Ternopil"
[22] "Cherkasy" "Kyiv" "Volyn" NA "Rivne" "Zakarpattia"
central_western_ukraine_states_name <- c("Volyn", "Rivne", "Lviv", "Ternopil", "Khmelnytskyi", "Ivano-Frankivsk", "Zakarpattia", "Chernivtsi", "Vinnytsia", "Cherkasy", "Kirovograd", "Poltava" )
conflict_central_western_ukraine <- conflict %>%
dplyr::filter(
event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
sub_event_type == "Shelling/artillery/missile attack",
admin1 %in% central_western_ukraine_states_name
)
number_of_events_central_western_ukraine <- conflict_central_western_ukraine %>%
group_by(latitude, longitude) %>%
summarize(number_of_events = n(), .groups = "drop")
central_western_ukraine <- subset(ukraine_states_rds, NAME_1 %in% central_ukraine_states_rds_names | NAME_1 %in% western_ukraine_states_rds_names)
central_western_ukraine_map <- ggplot() +
geom_polygon(data=central_western_ukraine, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
central_western_ukraine_map

central_western_ukraine_map +
geom_point(color="black", shape=21, fill="darkblue", alpha=0.6, data = number_of_events_central_western_ukraine, aes(x = longitude, y = latitude, size = number_of_events)) +
scale_size_continuous(range = c(1, 10), guide = 'legend', breaks = c(1, 10, 20, 50), labels = c("1", "10", "20", "50+")) +
labs(size = "Number of Events") +
labs(title = "Long-Range Strikes in Central and Western Ukraine", fontface="bold") +
labs(subtitle = "February 2022 - January 2023 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Interactive Map
library(leaflet)
Registered S3 methods overwritten by 'htmltools':
method from
print.html tools:rstudio
print.shiny.tag tools:rstudio
print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
method from
print.htmlwidget tools:rstudio
ukraine_interactive_map <- leaflet() %>%
addTiles() %>%
setView(lng = 37.7933, lat = 48.1450, zoom = 7)
ukraine_interactive_map
eastern_ukraine_states_names = list("Dnipropetrovsk", "Luhansk", "Donetsk", "Kharkiv", "Zaporizhia")
conflict_eastern_ukraine <- conflict %>%
dplyr::filter(
event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
event_type %in% c("Explosions/Remote violence", "Battles", "Violence against civilians"),
admin1 %in% eastern_ukraine_states_names)
events <- data.frame(latitude = conflict_eastern_ukraine$latitude,
longitude = conflict_eastern_ukraine$longitude)
m <- ukraine_interactive_map %>%
addCircleMarkers(data = events,
lng = ~longitude,
lat = ~latitude,
radius = 1,
color = "red",
fill = TRUE,
fillOpacity = 0.8)
# Display the map
m
m2 <- addPolygons(
map = m,
data = east_ukraine_states_rds,
fillColor = "orange",
fillOpacity = 0.2,
color = "black",
weight = 1
)
m2
Conclusion
The war in Ukraine has disrupted normal life and defied expectations
of a quick subjugation. The aggressive actions of Russia have exposed
millions of Ukrainians to violence and hardship. Mass graves indicate
potential atrocities in areas under Russian occupation. Contamination of
formerly occupied areas with mines poses a serious risk to returning
civilians. The war has led to a contraction of Ukraine’s economy and
internal and external displacement of millions. Remaining civilians face
ongoing disruptions to utilities and constant threats of cross-border
strikes and shelling. Ongoing occupation of a nuclear power plant by
Russia, along with the threats of nuclear weapons, present continuous
risks to the lives and environment of Ukraine and the surrounding
region.
Pre-Invasion
The Euromaidan protests, which started in late 2013, were primarily
centered in the capital city of Kyiv (Kiev) but spread to other regions
as well. The protests involved clashes between demonstrators and law
enforcement, resulting in instances of violence, injuries, and
fatalities.
Before the Russian invasion the violence in eastern Ukraine was
already concentrated in areas close to the Ukrainian-Russian border,
particularly in the Donetsk and Luhansk regions. Cities such as Donetsk,
Luhansk, Mariupol, and Sloviansk witnessed intense fighting and became
hotspots of violence.
Both sides of the conflict engaged in military operations, including
artillery shelling, sniper attacks, and armed clashes. The violence was
not limited to specific cities but was spread across the
conflict-affected regions.
The conflict resulted in a significant number of civilian casualties
and widespread displacement of residents. Civilians, including those
living in towns and villages near the front lines, faced the risk of
violence and were often caught in the crossfire.
ukraine_map2

centroid <- ukraine_states_rds$centroid <- coordinates(ukraine_states_rds)
text <- geom_text(data = , aes(x = centroid[, 1], y = centroid[, 2], label = ukraine_states_rds$NAME_1), color = "black", size = 4)
pi_ukraine_map <- ukraine_map2 +
geom_text(aes(x = centroid[, 1], y = centroid[, 2], label = ukraine_states_rds_names), size=2) + labs(title = "Pre-Invasion Conflicts", fontface="bold") + theme_void() + theme(plot.title = element_text(hjust = 0.5, face = "bold")) + coord_map(projection = "albers", lat0 = 49, lat1 = 54)
pi_ukraine_map

conflict_pi_ukraine <- conflict %>%
dplyr::filter(
event_date <= as.Date("2022-02-01"),
civilian_targeting != ""
)
number_of_events_pi_ukraine <- conflict_pi_ukraine %>%
group_by(longitude, latitude) %>%
reframe(number_of_events = n(), event_type)
pi_ukraine_map +
geom_point(data = number_of_events_pi_ukraine, aes(x = longitude, y = latitude, size = number_of_events, color=event_type)) +
geom_point(color="black", shape=21, data = number_of_events_pi_ukraine, aes(x = longitude, y = latitude, size = number_of_events, fill=event_type)) +
scale_size_continuous(range = c(0.1, 10)) +
labs(color = "Event Type", size = "Number of Events") +
labs(title = "Violence targeting Civilians in Pre-Invasion Ukraine", fontface="bold") +
labs(subtitle = "Before February 2022 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))
Coordinate system already present. Adding new coordinate system, which will replace the existing one.

Political Violence in Eastern Ukraine Pre-Invasion
conflict_eastern_ukraine_pi <- conflict %>%
dplyr::filter(
disorder_type == "Political violence",
event_date < as.Date("2022-02-01"),
event_type %in% c("Explosions/Remote violence", "Battles", "Violence against civilians"),
admin1 %in% eastern_ukraine_states_names)
event_counts_eastern_ukraine_pi <- conflict_eastern_ukraine_pi %>%
group_by(longitude, latitude) %>%
reframe(number_of_events = n(), event_type)
eastern_ukraine_map <- ggplot() +
geom_polygon(data=east_ukraine_states_rds, aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
eastern_ukraine_map

centroid <- east_ukraine_states_rds$centroid <- coordinates(east_ukraine_states_rds)
centroid[2] = centroid[2]+0.4
centroid[7] = centroid[7]-0.4
centroid[3] = centroid[3]-0.4
text <- geom_text(data = , aes(x = centroid[, 1], y = centroid[, 2], label = c("Dnipropetrovsk", "Donetsk", "Kharkiv", "Luhansk", "Zaporizhia")), color = "black", size = 4)
eastern_ukraine_map +
geom_point(data = event_counts_eastern_ukraine_pi, aes(x = longitude, y = latitude, size = number_of_events, color=event_type)) +
geom_point(color="black", shape=21, data = event_counts_eastern_ukraine_pi, aes(x = longitude, y = latitude, size = number_of_events, fill=event_type)) +
scale_size_continuous(range = c(0.1, 5)) +
labs(color = "Event Type", size = "Number of Events") +
labs(title = "Political Violence in Eastern Ukraine Pre-Invasion", fontface="bold") +
labs(subtitle = "February 2022 - January 2023 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5)) +
text

conflict_ukraine_pi_riots <- conflict %>%
dplyr::filter(
disorder_type == "Political violence",
event_date < as.Date("2022-02-01"),
event_type == "Riots"
)
ukraine_map2 +
geom_point(color="black", shape=21, fill="orange", alpha=0.6, data = conflict_ukraine_pi_riots, aes(x = longitude, y = latitude, size = 1)) +
labs(title = "Riots in Pre-Invasion Ukraine", fontface="bold") +
labs(subtitle = "Before February 2022 ") +
coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
guides(size = "none") +
theme_void() +
theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

LS0tCmF1dGhvcjogIkVsaWYgw4dheXNhciwgR2lyYXkgQ2/Fn2t1biwgU3VkZSBCdWtldCBLaXByaSwgWmV5bmVwIEFrYW50Igp0aXRsZTogIkVjb24gNDk0IFNwYXRpYWwgRGF0YSBTY2llbmNlIFByb2plY3QgLSBBbmFseXNpcyBvZiBBQ0xFRCBSZXBvcnQgV2FyIGluIFVrcmFpbmUiCm91dHB1dDogaHRtbF9ub3RlYm9vawppbnN0aXR1dGU6ICJTYWJhbmNpIFVuaXZlcnNpdHkiCmZvcm1hdDoKICBwZGY6IGRlZmF1bHQKZWRpdG9yOiB2aXN1YWwKLS0tCgojIEVDT04gNDk0IC0gU3BhdGlhbCBEYXRhIFNjaWVuY2UgUHJvamVjdAoKT3VyIHByb2plY3QgYWltZWQgdG8gYW5hbHl6ZSB0aGUgVWtyYWluZSBjb25mbGljdCB1c2luZyBzcGF0aWFsIGFuYWx5c2lzIGFuZCBtYXBzIGdlbmVyYXRlZCB0aHJvdWdoIGRhdGEgZnJvbSBBQ0xFRCAoQXJtZWQgQ29uZmxpY3QgTG9jYXRpb24gJiBFdmVudCBEYXRhIFByb2plY3QpLiBGb2N1c2luZyBvbiB0aGUgdmlvbGVuY2UgdGFyZ2V0aW5nIGNpdmlsaWFucyBhZnRlciBpbnZhc2lvbiBvZiBSdXNzaWEgaW50byBVa3JhaW5lLCB3ZSB1dGlsaXplZCBSIHByb2dyYW1taW5nIHRvIGV4dHJhY3QgYW5kIHZpc3VhbGl6ZSB0aGUgY29uZmxpY3QgZGF0YSwgZW5hYmxpbmcgdXMgdG8gcHJlc2VudCBhIGNvbXByZWhlbnNpdmUgb3ZlcnZpZXcgb2YgdGhlIGV2ZW50cyBhbmQgdGhlaXIgc3BhdGlhbCBkaXN0cmlidXRpb24uCgpgYGB7cn0KbGlicmFyeShzcCkKbGlicmFyeShyYXN0ZXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoY29uZmxpY3RlZCkKYGBgCgojIyBJbnRyb2R1Y3Rpb24KCi0gICBSdXNzaWEgaW52YWRlZCBVa3JhaW5lIGluIEZlYnJ1YXJ5IDIwMjIsIHJlc3VsdGluZyBpbiB0aGUgaGlnaGVzdCBsZXZlbHMgb2YgcG9saXRpY2FsIHZpb2xlbmNlIHJlY29yZGVkIGluIGEgc2luZ2xlIGNvdW50cnkgYnkgQUNMRUQuCgotICAgQ2l2aWxpYW5zIGluIFVrcmFpbmUgaGF2ZSBmYWNlZCBzaGVsbGluZywgaW5kaXNjcmltaW5hdGUgc3RyaWtlcywgZGVsaWJlcmF0ZSBhdHRhY2tzLCBhbmQgaGFyc2ggdHJlYXRtZW50IGluIG9jY3VwaWVkIGFyZWFzLgoKLSAgIFJ1c3NpYW4gZm9yY2VzIHRhcmdldGVkIEt5aXYgYnV0IHJldHJlYXRlZCBpbiBub3J0aGVybiBVa3JhaW5lIHdoaWxlIHF1aWNrbHkgc2VpemluZyB0ZXJyaXRvcmllcyBpbiBzb3V0aGVybiBhbmQgZWFzdGVybiByZWdpb25zLgoKLSAgIE92ZXIgNSwwMDAgcmVwb3J0ZWQgY2l2aWxpYW4gZmF0YWxpdGllcyBoYXZlIG9jY3VycmVkLCBidXQgdGhlIGFjdHVhbCB0b2xsIGlzIGxpa2VseSBtdWNoIGhpZ2hlci4KCi0gICBEaWZmZXJlbnQgcmVnaW9ucyBvZiBVa3JhaW5lIGV4cGVyaWVuY2VkIHZhcnlpbmcgbGV2ZWxzIG9mIHZpb2xlbmNlIGFuZCBvY2N1cGF0aW9uIGR1cmluZyB0aGUgY29uZmxpY3QuCgpgYGB7cn0KI3VrcmFpbmVfc3RhdGVzX3JkcyA8LSByYXN0ZXI6OmdldERhdGEoJ0dBRE0nLCBjb3VudHJ5ID0gIlVLUiIsIGxldmVsID0gMSkKdWtyYWluZV9zdGF0ZXNfcmRzID0gcmVhZFJEUygidWtyYWluZS5yZHMiKSAjaHR0cHM6Ly9nYWRtLm9yZy9kb3dubG9hZF9jb3VudHJ5Lmh0bWwKYGBgCgpgYGB7cn0KdWtyYWluZV9tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPXVrcmFpbmVfc3RhdGVzX3JkcywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IGlkKSwgZmlsbD0ib3JhbmdlIiwgYWxwaGEgPSAwLjYgKSArIGd1aWRlcyhmaWxsID0gIm5vbmUiKQp1a3JhaW5lX21hcApgYGAKCmBgYHtyfQplYXN0X3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyA8LSBsaXN0KCJEbmlwcm9wZXRyb3ZzJ2siLCAiRG9uZXRzJ2siLCAiTHVoYW5zJ2siICwgICJLaGFya2l2IiwgIlphcG9yaXpoemh5YSIpCgplYXN0X3VrcmFpbmVfc3RhdGVzX3JkcyA8LSBzdWJzZXQodWtyYWluZV9zdGF0ZXNfcmRzLCBOQU1FXzEgJWluJSBlYXN0X3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcykKYGBgCgpgYGB7cn0Kc291dGhfdWtyYWluZV9zdGF0ZXNfcmRzX25hbWVzIDwtIGxpc3QoIkNoZXJuaWhpdiIsICJLaWV2IiwgIktpZXYgQ2l0eSIsICJaaHl0b215ciIsICJTdW15IikKc291dGhfdWtyYWluZV9zdGF0ZXNfcmRzIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSAlaW4lIHNvdXRoX3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcykKYGBgCgpgYGB7cn0KY2VudHJhbF91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMgPC0gbGlzdCgiQ2hlcmthc3kiLCAiS2lyb3ZvaHJhZCIsICJQb2x0YXZhIiwgIlZpbm55dHN5YSIpCmNlbnRyYWxfdWtyYWluZV9zdGF0ZXNfcmRzIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSAlaW4lIGNlbnRyYWxfdWtyYWluZV9zdGF0ZXNfcmRzX25hbWVzKQpgYGAKCmBgYHtyfQp3ZXN0ZXJuX3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyA8LSBsaXN0KCJWb2x5biIsICJDaGVybml2dHNpIiwgIkl2YW5vLUZyYW5raXZzJ2siLCAiS2htZWwnbnl0cydreXkiLCAiUml2bmUiLCAiTCd2aXYiLCAiVGVybm9waWwnIiwgIlRyYW5zY2FycGF0aGlhIikKd2VzdGVybl91a3JhaW5lX3N0YXRlc19yZHMgPC0gc3Vic2V0KHVrcmFpbmVfc3RhdGVzX3JkcywgTkFNRV8xICVpbiUgd2VzdGVybl91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMpCmBgYAoKYGBge3J9CnNvdXRoZXJuX3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyA8LSBsaXN0KCJDcmltZWEiLCAiS2hlcnNvbiIsICAiTXlrb2xheWl2IiwgIk9kZXNzYSIpCnNvdXRoZXJuX3VrcmFpbmVfc3RhdGVzX3JkcyA8LSBzdWJzZXQodWtyYWluZV9zdGF0ZXNfcmRzLCBOQU1FXzEgJWluJSBzb3V0aGVybl91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMpCmBgYAoKYGBge3J9CnVrcmFpbmVfbWFwMiA8LSB1a3JhaW5lX21hcCArIAogIGdlb21fcG9seWdvbihkYXRhPWVhc3RfdWtyYWluZV9zdGF0ZXNfcmRzLCAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgZmlsbD0icmVkIiwgYWxwaGE9MC4yLCBjb2xvcj0iYmxhY2siKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9c291dGhfdWtyYWluZV9zdGF0ZXNfcmRzLCAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgZmlsbD0iYmxhY2siLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsKICBnZW9tX3BvbHlnb24oZGF0YT1jZW50cmFsX3VrcmFpbmVfc3RhdGVzX3JkcywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGZpbGw9ImRhcmtibHVlIiwgYWxwaGE9MC40LCBjb2xvcj0iYmxhY2siKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9d2VzdGVybl91a3JhaW5lX3N0YXRlc19yZHMsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJsaWdodGJsdWUiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsKICBnZW9tX3BvbHlnb24oZGF0YT1zb3V0aGVybl91a3JhaW5lX3N0YXRlc19yZHMsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpCgp1a3JhaW5lX21hcDIKYGBgCgpgYGB7cn0KY2VudHJvaWQgPC0gdWtyYWluZV9zdGF0ZXNfcmRzJGNlbnRyb2lkIDwtIGNvb3JkaW5hdGVzKHVrcmFpbmVfc3RhdGVzX3JkcykKdWtyYWluZV9zdGF0ZXNfcmRzX25hbWVzIDwtIHVrcmFpbmVfc3RhdGVzX3JkcyROQU1FXzEKYGBgCgpgYGB7cn0KdWtyYWluZV9tYXAzIDwtIHVrcmFpbmVfbWFwMiArIAogIGdlb21fdGV4dChhZXMoeCA9IGNlbnRyb2lkWywgMV0sIHkgPSBjZW50cm9pZFssIDJdLCBsYWJlbCA9IHVrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyksIHNpemU9MikgKyBsYWJzKHRpdGxlID0gIlJlZ2lvbnMgb2YgVWtyYWluZSIsIGZvbnRmYWNlPSJib2xkIikgKyB0aGVtZV92b2lkKCkgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSkgKyAgY29vcmRfbWFwKHByb2plY3Rpb24gPSAiYWxiZXJzIiwgbGF0MCA9IDQ5LCBsYXQxID0gNTQpCnVrcmFpbmVfbWFwMwpgYGAKCiMjIENvbmZsaWN0IERhdGEgKEFDTEVEKQoKYGBge3J9CmVhc3Rlcm5fdWtyYWluZV9zdGF0ZXNfbmFtZXMgPSBsaXN0KCJEbmlwcm9wZXRyb3ZzayIsICJMdWhhbnNrIiwgIkRvbmV0c2siLCAiS2hhcmtpdiIsICJaYXBvcml6aGlhIikKYGBgCgpgYGB7cn0KY29uZmxpY3QgPC0gcmVhZF9jc3YoJ3VrcmFpbmUuY3N2Jywgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkKY29uZmxpY3QkZXZlbnRfZGF0ZSA8LSBhcy5EYXRlKGNvbmZsaWN0JGV2ZW50X2RhdGUsIGZvcm1hdCA9ICIlZCAlQiAlWSIpCmBgYAoKYGBge3J9CnVuaXF1ZShjb25mbGljdCRhZG1pbjEpCmBgYAoKYGBge3J9CnVuaXF1ZShjb25mbGljdCRldmVudF90eXBlKQpgYGAKCmBgYHtyfQp1bmlxdWUoY29uZmxpY3Qkc3ViX2V2ZW50X3R5cGUpCmBgYAoKIyMgQXBwYXJlbnQgV2FyIENyaW1lcyBpbiBOb3J0aGVybiBVa3JhaW5lCgpJbiBub3J0aGVybiBVa3JhaW5lLCBBQ0xFRCByZWNvcmRzIG92ZXIgNDAwIGluY2lkZW50cyB0YXJnZXRpbmcgY2l2aWxpYW5zLCB3aXRoIGEgc2lnbmlmaWNhbnQgbnVtYmVyIG9jY3VycmluZyBkdXJpbmcgdGhlIFJ1c3NpYW4gYWR2YW5jZSBhbmQgc3Vic2VxdWVudCBvY2N1cGF0aW9uLiBTaGVsbGluZywgYXJ0aWxsZXJ5LCBhbmQgbWlzc2lsZSBhdHRhY2tzIHdlcmUgdGhlIG1vc3QgY29tbW9uIHR5cGVzIG9mIHZpb2xlbmNlLCBidXQgZGlyZWN0IGF0dGFja3Mgb24gY2l2aWxpYW4gcG9wdWxhdGlvbnMgcmVzdWx0ZWQgaW4gdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIHJlcG9ydGVkIGNpdmlsaWFuIGZhdGFsaXRpZXMuIE1hc3MgZ3JhdmVzIHdlcmUgZGlzY292ZXJlZCBmb2xsb3dpbmcgdGhlIFJ1c3NpYW4gcmV0cmVhdC4gVGhlIEt5aXYgcmVnaW9uLCBpbmNsdWRpbmcgdGhlIGNpdHkgb2YgS3lpdiwgd2FzIG1vc3QgYWZmZWN0ZWQgYnkgdGhlc2Ugc3RyaWtlcywgd2hpbGUgdGhlIFN1bXkgcmVnaW9uIGNvbnRpbnVlZCB0byBzdWZmZXIgZnJvbSBzdHJpa2VzIGFsb25nIGl0cyBib3JkZXIgYXJlYXMgd2l0aCBSdXNzaWEgdGhyb3VnaG91dCB0aGUgeWVhci4KSW5jaWRlbnRzIHJlbGF0ZWQgdG8gYWNjaWRlbnRhbCBkZXRvbmF0aW9uIG9mIG1pbmVzIGFuZCBleHBsb3NpdmVzIGNvbnRpbnVlZCB0byBvY2N1ciBkdXJpbmcgYW5kIGFmdGVyIHRoZSBpbnZhc2lvbi4gQUNMRUQgcmVjb3JkcyBhdCBsZWFzdCA0MyBzdWNoIGV2ZW50cyByZXN1bHRpbmcgaW4gYXQgbGVhc3QgMzQgcmVwb3J0ZWQgZmF0YWxpdGllcywgd2l0aCB0aGUgaGlnaGVzdCBpbmNpZGVuY2UgaW4gQXByaWwgYW5kIE1heSAyMDIyIGluIHRoZSBLeWl2IGFuZCBDaGVybmloaXYgcmVnaW9ucyBmb2xsb3dpbmcgdGhlIFJ1c3NpYW4gd2l0aGRyYXdhbC4KCmBgYHtyfQpmaWx0ZXJlZF9kYXRhIDwtIGNvbmZsaWN0ICU+JQogIGRwbHlyOjpmaWx0ZXIoZXZlbnRfZGF0ZSA+PSBhcy5EYXRlKCIyMDIyLTAyLTAxIikgJiBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjMtMDEtMzEiKSwKICAgICAgICAgICAgICAgIGNpdmlsaWFuX3RhcmdldGluZyE9IiIpCmBgYAoKYGBge3J9CmZpbHRlcmVkX2RhdGEgPC0gZmlsdGVyZWRfZGF0YVtmaWx0ZXJlZF9kYXRhJGFkbWluMSAlaW4lIGMoIlpoeXRvbXlyIiwgIkt5aXYgQ2l0eSIsICJLeWl2IiwgIlN1bXkiLCAiQ2hlcm5paGl2IiksXQpmaWx0ZXJlZF9kYXRhJG1vbnRoX3llYXIgPC0gZm9ybWF0KGZpbHRlcmVkX2RhdGEkZXZlbnRfZGF0ZSwgIiVCLSVZIikKYGBgCgpgYGB7cn0KZWFzdGVybiA8LSBmaWx0ZXJlZF9kYXRhW2ZpbHRlcmVkX2RhdGEkYWRtaW4xICVpbiUgYygiRG5pcHJvcGV0cm92c2siLCAiRG9uZXRzayIsICJLaGFya2l2IiwgIkx1aGFuc2siLCAiWmFwb3JpemhpYSIpLF0KZWFzdGVybiRtb250aF95ZWFyIDwtIGZvcm1hdChlYXN0ZXJuJGV2ZW50X2RhdGUsICIlQi0lWSIpCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBjYWxsZWQgJ25ld19ldmVudF90eXBlJwpmaWx0ZXJlZF9kYXRhJG5ld19ldmVudF90eXBlIDwtIE5BCgojIE1hcCB2YWx1ZXMgYmFzZWQgb24gJ3N1Yl9ldmVudF90eXBlJwpmaWx0ZXJlZF9kYXRhJG5ld19ldmVudF90eXBlW2ZpbHRlcmVkX2RhdGEkc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIsICJBdHRhY2siLCAiQWlyL2Ryb25lIHN0cmlrZSIsICJTaGVsbGluZy9hcnRpbGxlcnkvbWlzc2lsZSBhdHRhY2siKV0gPC0gZmlsdGVyZWRfZGF0YSRzdWJfZXZlbnRfdHlwZVtmaWx0ZXJlZF9kYXRhJHN1Yl9ldmVudF90eXBlICVpbiUgYygiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiLCAiQXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIildCmZpbHRlcmVkX2RhdGEkbmV3X2V2ZW50X3R5cGVbIShmaWx0ZXJlZF9kYXRhJHN1Yl9ldmVudF90eXBlICVpbiUgYygiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiLCAiQXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIikpXSA8LSAiT3RoZXIgdmlvbGVuY2UiCmBgYAoKYGBge3J9CmdncGxvdChmaWx0ZXJlZF9kYXRhLCBhZXMoeCA9IG1vbnRoX3llYXIsIGZpbGwgPSBuZXdfZXZlbnRfdHlwZSwgKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIikgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJOdW1iZXIgb2YgRXZlbnRzIiwgdGl0bGUgPSAiVmlvbGVuY2UgVGFyZ2V0aW5nIENpdmlsaWFucyBpbiBOb3J0aGVybiBVa3JhaW5lIiwKICAgICAgIHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMiLAogICAgICAgZmlsbCA9ICJTdWItRXZlbnQgVHlwZSIpICsKICB0aGVtZV9idygpCmBgYApgYGB7cn0KIyBDb252ZXJ0IG1vbnRoX3llYXIgY29sdW1uIHRvIHByb3BlciBkYXRlIGZvcm1hdApmaWx0ZXJlZF9kYXRhJG1vbnRoX3llYXIgPC0gYXMuRGF0ZShwYXN0ZTAoIjAxLSIsIGZpbHRlcmVkX2RhdGEkbW9udGhfeWVhciksIGZvcm1hdCA9ICIlZC0lQi0lWSIpCgojIFNvcnQgdGhlIGRhdGEgYnkgdGhlIG1vbnRoX3llYXIgY29sdW1uCmZpbHRlcmVkX2RhdGEgPC0gZmlsdGVyZWRfZGF0YVtvcmRlcihmaWx0ZXJlZF9kYXRhJG1vbnRoX3llYXIpLCBdCgoKIyBDcmVhdGUgdGhlIGJhciBjaGFydApnZ3Bsb3QoZmlsdGVyZWRfZGF0YSwgYWVzKHggPSBtb250aF95ZWFyLCBmaWxsID0gbmV3X2V2ZW50X3R5cGUsICkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIpICsKICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiTnVtYmVyIG9mIEV2ZW50cyIsIHRpdGxlID0gIlZpb2xlbmNlIFRhcmdldGluZyBDaXZpbGlhbnMgaW4gTm9ydGhlcm4gVWtyYWluZSIsCiAgICAgICBzdWJ0aXRsZSA9ICJGZWJydWFyeSAyMDIyIC0gSmFudWFyeSAyMDIzIiwKICAgICAgIGZpbGwgPSAiU3ViLUV2ZW50IFR5cGUiKSArCiAgdGhlbWVfYncoKQoKYGBgCgpgYGB7cn0KCiMgQ29udmVydCBtb250aF95ZWFyIGNvbHVtbiB0byBwcm9wZXIgZGF0ZSBmb3JtYXQKZWFzdGVybiRtb250aF95ZWFyIDwtIGFzLkRhdGUocGFzdGUwKCIwMS0iLCBlYXN0ZXJuJG1vbnRoX3llYXIpLCBmb3JtYXQgPSAiJWQtJUItJVkiKQoKIyBTb3J0IHRoZSBkYXRhIGJ5IHRoZSBtb250aF95ZWFyIGNvbHVtbgplYXN0ZXJuIDwtIGVhc3Rlcm5bb3JkZXIoZWFzdGVybiRtb250aF95ZWFyKSwgXQoKCiMgQ3JlYXRlIHRoZSBiYXIgY2hhcnQKZ2dwbG90KGVhc3Rlcm4sIGFlcyh4ID0gbW9udGhfeWVhciwgZmlsbCA9IGFkbWluMSwgKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIikgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJOdW1iZXIgb2YgRXZlbnRzIiwgdGl0bGUgPSAiVmlvbGVuY2UgVGFyZ2V0aW5nIENpdmlsaWFucyBpbiBFYXN0ZXJuIFVrcmFpbmUiLAogICAgICAgc3VidGl0bGUgPSAiRmVicnVhcnkgMjAyMiAtIEphbnVhcnkgMjAyMyIsCiAgICAgICBmaWxsID0gIlJlZ2lvbiIpICsKICB0aGVtZV9idygpCmBgYAoKCiMjIEhlYXZ5IEZpZ2h0aW5nIEFsb25nIHRoZSBGcm9udGxpbmUgaW4gRWFzdGVybiBVa3JhaW5lCgpFYXN0ZXJuIFVrcmFpbmUgZmFjZXMgdW5wcmVjZWRlbnRlZCB2aW9sZW5jZSwgd2l0aCB0aHJlZS1xdWFydGVycyBvZiBwb2xpdGljYWwgdmlvbGVuY2UgZXZlbnRzIG9jY3VycmluZyBpbiB0aGUgcmVnaW9uLCBwcmltYXJpbHkgZHVlIHRvIHNoZWxsaW5nLCBhcnRpbGxlcnksIGFuZCBtaXNzaWxlIGF0dGFja3MuIERlc3BpdGUgcmVsYXRpdmUgZGlzdGFuY2UgZnJvbSB0aGUgZnJvbnRsaW5lLCB0aGUgRG5pcHJvcGV0cm92c2sgcmVnaW9uIHJlbWFpbnMgYXQgcmlzaywgYXMgUnVzc2lhIGNvbnRpbnVlcyBhaXIgYW5kIG1pc3NpbGUgc3RyaWtlcywgZXhlbXBsaWZpZWQgYnkgdGhlIGRlYWRseSBpbmNpZGVudCBpbiBEbmlwcm8gb24gMTQgSmFudWFyeSAyMDIzLgoKIyMjIFBvbGl0aWNhbCBWaW9sZW5jZSBpbiBFYXN0ZXJuIFVrcmFpbmUKCkVhc3Rlcm4gcGFydHMgb2YgZWFzdGVybiBVa3JhaW5lIGhhcyBiZWVuIGhpZ2hseSBjb250ZXN0ZWQgc2luY2UgdGhlIGJlZ2lubmluZyBvZiB0aGUgaW52YXNpb24uIFRoZSBlYXN0ZXJuIHBvcnRpb24gb2YgdGhlIEtoYXJraXYgcmVnaW9uLCB3aGljaCB3YXMgb2NjdXBpZWQgYnkgUnVzc2lhbiBmb3JjZXMsIHNlcnZlZCBhcyBhIGJhc2UgZm9yIHRoZWlyIG9mZmVuc2l2ZXMgaW4gdGhlIEx1aGFuc2sgYW5kIERvbmV0c2sgcmVnaW9ucy4gVGhlIEx1aGFuc2sgcmVnaW9uIGV4cGVyaWVuY2VkIGludGVuc2UgdmlvbGVuY2UgYmV0d2VlbiBsYXRlIEZlYnJ1YXJ5IGFuZCBtaWQtc3VtbWVyIDIwMjIsIGFzIFJ1c3NpYW4gZm9yY2VzIGNhcHR1cmVkIHRvd25zIGJ5IGRlc3Ryb3lpbmcgdGhlbSB3aXRoIGFydGlsbGVyeS4gQSBzaW1pbGFyIGFwcHJvYWNoIHdhcyBlbXBsb3llZCBpbiB0aGUgc3ByaW5nIG9mIDIwMjIgdG8gY2FwdHVyZSBNYXJpdXBvbCwgdGhlIGxhc3QgVWtyYWluaWFuIHN0cm9uZ2hvbGQgaW4gdGhlIHNvdXRoZXJuIERvbmV0c2sgcmVnaW9uLCByZXN1bHRpbmcgaW4gZGlyZSBjb25zZXF1ZW5jZXMgZm9yIGJvdGggdHJhcHBlZCBVa3JhaW5pYW4gbWlsaXRhcnkgcGVyc29ubmVsIGFuZCBjaXZpbGlhbnMuIFRoZSBaYXBvcml6aGlhIHJlZ2lvbiBleHBlcmllbmNlZCByZWxhdGl2ZWx5IGxvd2VyIGxldmVscyBvZiBhcm1lZCB2aW9sZW5jZSBkdWUgdG8gUnVzc2lhJ3Mgc3dpZnQgb2NjdXBhdGlvbiBpbiBsYXRlIEZlYnJ1YXJ5IGFuZCBlYXJseSBNYXJjaCAyMDIyLgoKCmBgYHtyfQpjb25mbGljdF9lYXN0ZXJuX3VrcmFpbmUgPC0gY29uZmxpY3QgJT4lCiAgZHBseXI6OmZpbHRlcigKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPj0gYXMuRGF0ZSgiMjAyMi0wMi0wMSIpICYgZXZlbnRfZGF0ZSA8PSBhcy5EYXRlKCIyMDIzLTAxLTMxIiksCiAgICAgICAgICAgICAgICBldmVudF90eXBlICVpbiUgYygiRXhwbG9zaW9ucy9SZW1vdGUgdmlvbGVuY2UiLCAiQmF0dGxlcyIsICJWaW9sZW5jZSBhZ2FpbnN0IGNpdmlsaWFucyIpLAogICAgICAgICAgICAgICAgYWRtaW4xICVpbiUgZWFzdGVybl91a3JhaW5lX3N0YXRlc19uYW1lcykKYGBgCgpgYGB7cn0KZXZlbnRfY291bnRzX2Vhc3Rlcm5fdWtyYWluZSA8LSBjb25mbGljdF9lYXN0ZXJuX3VrcmFpbmUgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBldmVudF90eXBlKQpgYGAKCmBgYHtyfQplYXN0X3VrcmFpbmVfc3RhdGVzX3JkcwpgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfbWFwIDwtIGdncGxvdCgpICsKICBnZW9tX3BvbHlnb24oZGF0YT1lYXN0X3VrcmFpbmVfc3RhdGVzX3JkcywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGZpbGw9Im9yYW5nZSIsIGFscGhhPTAuMiwgY29sb3I9ImJsYWNrIikgKyBndWlkZXMoZmlsbCA9ICJub25lIikgKyB0aGVtZV92b2lkKCkKZWFzdGVybl91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpjZW50cm9pZCA8LSBlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcyRjZW50cm9pZCA8LSBjb29yZGluYXRlcyhlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcykKY2VudHJvaWRbMl0gPSBjZW50cm9pZFsyXSswLjQKY2VudHJvaWRbN10gPSBjZW50cm9pZFs3XS0wLjQKY2VudHJvaWRbM10gPSBjZW50cm9pZFszXS0wLjQKdGV4dCA8LSBnZW9tX3RleHQoZGF0YSA9ICwgYWVzKHggPSBjZW50cm9pZFssIDFdLCB5ID0gY2VudHJvaWRbLCAyXSwgbGFiZWwgPSBjKCJEbmlwcm9wZXRyb3ZzayIsICJEb25ldHNrIiwgIktoYXJraXYiLCAiTHVoYW5zayIsICJaYXBvcml6aGlhIikpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA0KQpgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBldmVudF9jb3VudHNfZWFzdGVybl91a3JhaW5lLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgY29sb3I9ZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gZXZlbnRfY291bnRzX2Vhc3Rlcm5fdWtyYWluZSwgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMsIGZpbGw9ZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgNSkpICsKICBsYWJzKGNvbG9yID0gIkV2ZW50IFR5cGUiLCBzaXplID0gIk51bWJlciBvZiBFdmVudHMiKSArCiAgbGFicyh0aXRsZSA9ICJQb2xpdGljYWwgVmlvbGVuY2UgaW4gRWFzdGVybiBVa3JhaW5lIiwgZm9udGZhY2U9ImJvbGQiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiRmVicnVhcnkgMjAyMiAtIEphbnVhcnkgMjAyMyAiKSArCiAgY29vcmRfbWFwKHByb2plY3Rpb24gPSAiYWxiZXJzIiwgbGF0MCA9IDQ5LCBsYXQxID0gNTQpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsKICB0ZXh0CmBgYAoKIyMjIENvbmZsaWN0IGluIEtoYXJraXYKCkRlc3BpdGUgZmFpbGluZyB0byBicmVhayBVa3JhaW5pYW4gZGVmZW5zZXMgaW4gYW5kIGFyb3VuZCBLaGFya2l2IGNpdHksIFJ1c3NpYW4gZm9yY2VzIGhhZCB0YWtlbiBjb250cm9sIG9mIHRoZSBtYWpvcml0eSBvZiB0aGUgbm9ydGhlcm4gYW5kIGVhc3Rlcm4gcGFydHMgb2YgdGhlIHJlZ2lvbiBieSBBcHJpbCAyMDIyLCBpbmNsdWRpbmcgdGhlIHN0cmF0ZWdpY2FsbHkgaW1wb3J0YW50IHRyYW5zcG9ydCBodWIgb2YgSXppdW0uIEhvd2V2ZXIsIFVrcmFpbmUgbWFuYWdlZCB0byBsaWJlcmF0ZSBhbG1vc3QgdGhlIGVudGlyZSByZWdpb24gaW4gYW4gdW5leHBlY3RlZCBjb3VudGVyLW9mZmVuc2l2ZSBpbiBTZXB0ZW1iZXIgMjAyMi4gQW1vbmcgdGhlIG1vcmUgdGhhbiA4MDAgaW5jaWRlbnRzIHRhcmdldGluZyBjaXZpbGlhbnMsIGFwcHJveGltYXRlbHkgdGhyZWUtcXVhcnRlcnMgaW52b2x2ZWQgYXJ0aWxsZXJ5LCBtaXNzaWxlcywgYW5kIGFpcnN0cmlrZXMsIHdoaWNoIGFsc28gYWNjb3VudGVkIGZvciB0aGUgbWFqb3JpdHkgb2YgcmVwb3J0ZWQgY2l2aWxpYW4gZGVhdGhzIGluIHRoZSByZWdpb24uIEFyb3VuZCBvbmUtdGhpcmQgb2YgdGhlc2UgaW5jaWRlbnRzIG9jY3VycmVkIGluIE1hcmNoIDIwMjIgYWxvbmUuCgpgYGB7cn0KY29uZmxpY3Rfa2hhcmtpdiA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgY2l2aWxpYW5fdGFyZ2V0aW5nICE9ICIiLAogICAgICAgICAgICAgICAgZXZlbnRfZGF0ZSA+PSBhcy5EYXRlKCIyMDIyLTAyLTAxIikgJiBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjMtMDEtMzEiKSwKICAgICAgICAgICAgICAgIGFkbWluMSA9PSAiS2hhcmtpdiIpCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBjYWxsZWQgJ25ld19ldmVudF90eXBlJwpjb25mbGljdF9raGFya2l2JG5ld19ldmVudF90eXBlIDwtIE5BCgojIE1hcCB2YWx1ZXMgYmFzZWQgb24gJ3N1Yl9ldmVudF90eXBlJwpjb25mbGljdF9raGFya2l2JG5ld19ldmVudF90eXBlW2NvbmZsaWN0X2toYXJraXYkc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJTaGVsbGluZy9hcnRpbGxlcnkvbWlzc2lsZSBhdHRhY2siLCAiQWlyL2Ryb25lIHN0cmlrZSIsICJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIsICJBdHRhY2siKV0gPC0gY29uZmxpY3Rfa2hhcmtpdiRzdWJfZXZlbnRfdHlwZVtjb25mbGljdF9raGFya2l2JHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiLCAiQXR0YWNrIildCmNvbmZsaWN0X2toYXJraXYkbmV3X2V2ZW50X3R5cGVbIShjb25mbGljdF9raGFya2l2JHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiLCAiQXR0YWNrIikpXSA8LSAiT3RoZXIgdmlvbGVuY2UiCmBgYAoKYGBge3J9Cm51bWJlcl9vZl9ldmVudHNfa2hhcmtpdiA8LSBjb25mbGljdF9raGFya2l2ICU+JQogIGdyb3VwX2J5KGxvbmdpdHVkZSwgbGF0aXR1ZGUpICU+JQogIHJlZnJhbWUobnVtYmVyX29mX2V2ZW50cyA9IG4oKSwgbmV3X2V2ZW50X3R5cGUpCmBgYAoKYGBge3J9CmtoYXJraXYgPC0gc3Vic2V0KHVrcmFpbmVfc3RhdGVzX3JkcywgTkFNRV8xID09ICJLaGFya2l2IikKa2hhcmtpdl9tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPWtoYXJraXYsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgdGhlbWVfdm9pZCgpCmtoYXJraXZfbWFwCmBgYAoKYGBge3J9CmtoYXJraXZfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBudW1iZXJfb2ZfZXZlbnRzX2toYXJraXYsIGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIHNpemUgPSBudW1iZXJfb2ZfZXZlbnRzLCBjb2xvcj1uZXdfZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c19raGFya2l2LCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgZmlsbD1uZXdfZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgMTApKSArCiAgbGFicyhjb2xvciA9ICJTdWItRXZlbnQgVHlwZSIsIHNpemUgPSAiTnVtYmVyIG9mIEV2ZW50cyIpICsKICBsYWJzKHRpdGxlID0gIlZpb2xlbmNlIHRhcmdldGluZyBDaXZpbGlhbnMgaW4gS2hhcmtpdiIsIGZvbnRmYWNlPSJib2xkIikgKyAKICBsYWJzKHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgojIyMgQ29uZmxpY3QgaW4gTHVoYW5zawoKVGhlIGV4dGVuc2l2ZSB1c2Ugb2YgYXJ0aWxsZXJ5LCBtaXNzaWxlcywgYW5kIGFpcnN0cmlrZXMsIGFsb25nIHdpdGggaW50ZW5zZSBjbG9zZSBjb21iYXQsIHJlc3VsdGVkIGluIHNpZ25pZmljYW50IHN1ZmZlcmluZyBmb3IgdGhlIGNpdmlsaWFuIHBvcHVsYXRpb24gaW4gdGhlIEx1aGFuc2sgcmVnaW9uLiBUcmFnaWMgaW5jaWRlbnRzIG9jY3VycmVkLCBzdWNoIGFzIHRoZSBzaGVsbGluZyBvZiBhIG51cnNpbmcgaG9tZSBpbiBLcmVtaW5uYSBvbiBNYXJjaCAxMSwgMjAyMiwgd2hpY2ggcmVwb3J0ZWRseSBsZWQgdG8gdGhlIGRlYXRoIG9mIDU2IGVsZGVybHkgcGF0aWVudHMuIEFkZGl0aW9uYWxseSwgYW4gYWlyc3RyaWtlIG9uIGEgc2Nob29sIHVzZWQgYXMgYSBzaGVsdGVyIGluIEJpbG9ob3JpdmthIG9uIE1heSA3LCAyMDIyLCByZXN1bHRlZCBpbiB0aGUgbG9zcyBvZiBhdCBsZWFzdCA2MCBsaXZlcy4gVGhlIHNoZWxsaW5nIG9mIFNldmVyb2RvbmV0c2sgaW4gTWFyY2ggYW5kIE1heSAyMDIyIGFsc28gY2xhaW1lZCB0aGUgbGl2ZXMgb2Ygb3ZlciA1MCBjaXZpbGlhbnMuIEFmdGVyIHRoZSBSdXNzaWFuIG9jY3VwYXRpb24gb2YgdGhlIHJlZ2lvbiBpbiB0aGUgc3VtbWVyIG9mIDIwMjIsIHRoZXJlIHdhcyBhIHNpZ25pZmljYW50IGRlY3JlYXNlIGluIHJlcG9ydHMgb2YgY2l2aWxpYW5zIGJlaW5nIHRhcmdldGVkLCBhbHRob3VnaCB0aGUgcmVnaW9uIGhhcyByZW1haW5lZCBoaWdobHkgdm9sYXRpbGUsIHBhcnRpY3VsYXJseSBzaW5jZSBhdXR1bW4uIAoKYGBge3J9CmNvbmZsaWN0X2x1aGFuc2sgPC0gY29uZmxpY3QgJT4lCiAgZHBseXI6OmZpbHRlcigKICAgICAgICAgICAgICAgIGNpdmlsaWFuX3RhcmdldGluZyAhPSAiIiwKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPj0gYXMuRGF0ZSgiMjAyMi0wMi0wMSIpICYgZXZlbnRfZGF0ZSA8PSBhcy5EYXRlKCIyMDIzLTAxLTMxIiksCiAgICAgICAgICAgICAgICBhZG1pbjEgPT0gIkx1aGFuc2siKQpgYGAKCmBgYHtyfQojIENyZWF0ZSBhIG5ldyBjb2x1bW4gY2FsbGVkICduZXdfZXZlbnRfdHlwZScKY29uZmxpY3RfbHVoYW5zayRuZXdfZXZlbnRfdHlwZSA8LSBOQQoKIyBNYXAgdmFsdWVzIGJhc2VkIG9uICdzdWJfZXZlbnRfdHlwZScKY29uZmxpY3RfbHVoYW5zayRuZXdfZXZlbnRfdHlwZVtjb25mbGljdF9sdWhhbnNrJHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJBdHRhY2siKV0gPC0gY29uZmxpY3RfbHVoYW5zayRzdWJfZXZlbnRfdHlwZVtjb25mbGljdF9sdWhhbnNrJHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJBdHRhY2siKV0KY29uZmxpY3RfbHVoYW5zayRuZXdfZXZlbnRfdHlwZVshKGNvbmZsaWN0X2x1aGFuc2skc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJTaGVsbGluZy9hcnRpbGxlcnkvbWlzc2lsZSBhdHRhY2siLCAiQWlyL2Ryb25lIHN0cmlrZSIsICJBYmR1Y3Rpb24vZm9yY2VkIGRpc2FwcGVhcmFuY2UiICwgIkF0dGFjayIpKV0gPC0gIk90aGVyIHZpb2xlbmNlIgpgYGAKCmBgYHtyfQpudW1iZXJfb2ZfZXZlbnRzX2x1aGFuc2sgPC0gY29uZmxpY3RfbHVoYW5zayAlPiUKICBncm91cF9ieShsb25naXR1ZGUsIGxhdGl0dWRlKSAlPiUKICByZWZyYW1lKG51bWJlcl9vZl9ldmVudHMgPSBuKCksIG5ld19ldmVudF90eXBlKQpgYGAKCmBgYHtyfQpsdWhhbnNrIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSA9PSAiTHVoYW5zJ2siKQpsdWhhbnNrX21hcCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9bHVoYW5zaywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGZpbGw9Im9yYW5nZSIsIGFscGhhPTAuMiwgY29sb3I9ImJsYWNrIikgKyBndWlkZXMoZmlsbCA9ICJub25lIikgKyB0aGVtZV92b2lkKCkKbHVoYW5za19tYXAKYGBgCgpgYGB7cn0KbHVoYW5za19tYXAgKwogIGdlb21fcG9pbnQoZGF0YSA9IG51bWJlcl9vZl9ldmVudHNfbHVoYW5zaywgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMsIGNvbG9yPW5ld19ldmVudF90eXBlKSkgKwogIGdlb21fcG9pbnQoY29sb3I9ImJsYWNrIiwgc2hhcGU9MjEsIGRhdGEgPSBudW1iZXJfb2ZfZXZlbnRzX2x1aGFuc2ssIGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIHNpemUgPSBudW1iZXJfb2ZfZXZlbnRzLCBmaWxsPW5ld19ldmVudF90eXBlKSkgKwogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMC4xLCAxMCkpICsKICBsYWJzKGNvbG9yID0gIlN1Yi1FdmVudCBUeXBlIiwgc2l6ZSA9ICJOdW1iZXIgb2YgRXZlbnRzIikgKwogIGxhYnModGl0bGUgPSAiVmlvbGVuY2UgdGFyZ2V0aW5nIENpdmlsaWFucyBpbiBMdWhhbnNrIiwgZm9udGZhY2U9ImJvbGQiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiRmVicnVhcnkgMjAyMiAtIEphbnVhcnkgMjAyMyAiKSArCiAgY29vcmRfbWFwKHByb2plY3Rpb24gPSAiYWxiZXJzIiwgbGF0MCA9IDQ5LCBsYXQxID0gNTQpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlPSJib2xkIiksIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCiMjIyBDb25mbGljdCBpbiBEb25ldHNrCgpBQ0xFRCBkYXRhIGRvY3VtZW50cyBtb3JlIHRoYW4gMTYsMDAwIGluY2lkZW50cyBpbiB0aGUgRG9uZXRzayByZWdpb24sIHdpdGggb3ZlciAxMiwwMDAgb2YgdGhlbSBpbnZvbHZpbmcgc2hlbGxpbmcsIGFydGlsbGVyeSwgbWlzc2lsZXMsIGFuZCBhaXJzdHJpa2VzLiBPbmx5IGEgcmVsYXRpdmVseSBzbWFsbCBudW1iZXIgb2YgdGhlc2UgaW5jaWRlbnRzLCBhcm91bmQgODAwLCBzcGVjaWZpY2FsbHkgdGFyZ2V0ZWQgY2l2aWxpYW5zLiBQcmlvciB0byB0aGUgUnVzc2lhbiBvY2N1cGF0aW9uLCB0aGUgY2l0eSBvZiBNYXJpdXBvbCB3aXRuZXNzZWQgbXVsdGlwbGUgaW5jaWRlbnRzIHJlc3VsdGluZyBpbiBzaWduaWZpY2FudCBjYXN1YWx0aWVzLiBNYXNzIGNhc3VhbHR5IGV2ZW50cyBjYXVzZWQgYnkgbG9uZy1yYW5nZSBtaXNzaWxlIGFuZCBhcnRpbGxlcnkgc3RyaWtlcyB3ZXJlIHJlcG9ydGVkIGluIHZhcmlvdXMgYXJlYXMgb2YgdGhlIHJlZ2lvbiwgYWZmZWN0aW5nIGJvdGggc2lkZXMgb2YgdGhlIGxpbmUgb2YgY29udGFjdC4KCmBgYHtyfQpjb25mbGljdF9kb25ldHNrIDwtIGNvbmZsaWN0ICU+JQogIGRwbHlyOjpmaWx0ZXIoCiAgICAgICAgICAgICAgICBjaXZpbGlhbl90YXJnZXRpbmcgIT0gIiIsCiAgICAgICAgICAgICAgICBldmVudF9kYXRlID49IGFzLkRhdGUoIjIwMjItMDItMDEiKSAmIGV2ZW50X2RhdGUgPD0gYXMuRGF0ZSgiMjAyMy0wMS0zMSIpLAogICAgICAgICAgICAgICAgYWRtaW4xID09ICJEb25ldHNrIikKYGBgCgpgYGB7cn0KIyBDcmVhdGUgYSBuZXcgY29sdW1uIGNhbGxlZCAnbmV3X2V2ZW50X3R5cGUnCmNvbmZsaWN0X2RvbmV0c2skbmV3X2V2ZW50X3R5cGUgPC0gTkEKCiMgTWFwIHZhbHVlcyBiYXNlZCBvbiAnc3ViX2V2ZW50X3R5cGUnCmNvbmZsaWN0X2RvbmV0c2skbmV3X2V2ZW50X3R5cGVbY29uZmxpY3RfZG9uZXRzayRzdWJfZXZlbnRfdHlwZSAlaW4lIGMoIlNoZWxsaW5nL2FydGlsbGVyeS9taXNzaWxlIGF0dGFjayIsICJBaXIvZHJvbmUgc3RyaWtlIiwgIkFiZHVjdGlvbi9mb3JjZWQgZGlzYXBwZWFyYW5jZSIgLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiKV0gPC0gY29uZmxpY3RfZG9uZXRzayRzdWJfZXZlbnRfdHlwZVtjb25mbGljdF9kb25ldHNrJHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIpXQpjb25mbGljdF9kb25ldHNrJG5ld19ldmVudF90eXBlWyEoY29uZmxpY3RfZG9uZXRzayRzdWJfZXZlbnRfdHlwZSAlaW4lIGMoIlNoZWxsaW5nL2FydGlsbGVyeS9taXNzaWxlIGF0dGFjayIsICJBaXIvZHJvbmUgc3RyaWtlIiwgIkFiZHVjdGlvbi9mb3JjZWQgZGlzYXBwZWFyYW5jZSIgLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiKSldIDwtICJPdGhlciB2aW9sZW5jZSIKYGBgCgpgYGB7cn0KbnVtYmVyX29mX2V2ZW50c19kb25ldHNrIDwtIGNvbmZsaWN0X2RvbmV0c2sgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBuZXdfZXZlbnRfdHlwZSkKYGBgCgpgYGB7cn0KZG9uZXRzayA8LSBzdWJzZXQodWtyYWluZV9zdGF0ZXNfcmRzLCBOQU1FXzEgPT0gIkRvbmV0cydrIikKZG9uZXRza19tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPWRvbmV0c2ssICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgdGhlbWVfdm9pZCgpCmRvbmV0c2tfbWFwCmBgYAoKYGBge3J9CmRvbmV0c2tfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBudW1iZXJfb2ZfZXZlbnRzX2RvbmV0c2ssIGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIHNpemUgPSBudW1iZXJfb2ZfZXZlbnRzLCBjb2xvcj1uZXdfZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c19kb25ldHNrLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgZmlsbD1uZXdfZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgMTApKSArCiAgbGFicyhjb2xvciA9ICJTdWItRXZlbnQgVHlwZSIsIHNpemUgPSAiTnVtYmVyIG9mIEV2ZW50cyIpICsKICBsYWJzKHRpdGxlID0gIlZpb2xlbmNlIHRhcmdldGluZyBDaXZpbGlhbnMgaW4gRG9uZXRzayIsIGZvbnRmYWNlPSJib2xkIikgKyAKICBsYWJzKHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgojIyMgQ29uZmxpY3QgaW4gWmFwb3JpemhpYQoKRHVyaW5nIHRoZSBpbml0aWFsIHN0YWdlcyBvZiB0aGUgaW52YXNpb24sIFJ1c3NpYW4gZm9yY2VzIHN1Y2Nlc3NmdWxseSBvY2N1cGllZCBhIHNpZ25pZmljYW50IHBvcnRpb24gb2YgdGhlIFphcG9yaXpoaWEgcmVnaW9uLiBUaGlzIGluY2x1ZGVkIHRoZSBlbnRpcmUgY29hc3RsaW5lIG9mIHRoZSBTZWEgb2YgQXpvdiwgZW5jb21wYXNzaW5nIHRoZSBVa3JhaW5pYW4gbmF2eSBiYXNlIGluIEJlcmRpYW5zaywgYXMgd2VsbCBhcyBhbiBhcmVhIGV4dGVuZGluZyBmcm9tIEtoZXJzb24gdG8gdGhlIHNvdXRoZXJuIERvbmV0c2sgcmVnaW9ucywgcmVhY2hpbmcgdGhlIERuaXBybyByaXZlci4gVGhlIG9jY3VwYXRpb24gYWxzbyBjb3ZlcmVkIE1lbGl0b3BvbCwgdGhlIHJlZ2lvbidzIHNlY29uZC1sYXJnZXN0IHRvd24uIFVrcmFpbmlhbiBmb3JjZXMgbWFuYWdlZCB0byBoYWx0IHRoZSBhZHZhbmNlbWVudCBvZiBSdXNzaWFuIGZvcmNlcyBpbiB0aGUgT3Jpa2hpdiBhbmQgSHVsaWFpcG9sZSBhcmVhcy4gV2hpbGUgYXBwcm94aW1hdGVseSBoYWxmIG9mIHRoZSBpbmNpZGVudHMgdGFyZ2V0aW5nIGNpdmlsaWFucyBpbiB0aGUgWmFwb3JpemhpYSByZWdpb24gaW52b2x2ZWQgc2hlbGxpbmcsIGFpciBhdHRhY2tzLCBhbmQgZHJvbmUgc3RyaWtlcywgY2l2aWxpYW5zIGhhdmUgYWxzbyBiZWVuIGRpcmVjdGx5IHRhcmdldGVkLiBUaGVzZSBhdHRhY2tzIGluY2x1ZGUgZmlyaW5nIGF0IHZlaGljbGVzIGNhcnJ5aW5nIGV2YWN1YXRpbmcgY2l2aWxpYW5zLCBhcyB3ZWxsIGFzIGluc3RhbmNlcyBvZiB0b3J0dXJlIGFuZCBleGVjdXRpb24uIEluIGFyZWFzIHVuZGVyIFJ1c3NpYW4gb2NjdXBhdGlvbiwgdGhlcmUgYXJlIGZyZXF1ZW50IHJlcG9ydHMgb2YgdGhlIGFiZHVjdGlvbiBvZiBsb2NhbCBvZmZpY2lhbHMsIHRlYWNoZXJzLCBqb3VybmFsaXN0cywgVWtyYWluaWFuIGFybXkgdmV0ZXJhbnMsIGFuZCBjaXZpbCBhY3RpdmlzdHMuCgpgYGB7cn0KY29uZmxpY3RfemFwb3JpemhpYSA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgY2l2aWxpYW5fdGFyZ2V0aW5nICE9ICIiLAogICAgICAgICAgICAgICAgZXZlbnRfZGF0ZSA+PSBhcy5EYXRlKCIyMDIyLTAyLTAxIikgJiBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjMtMDEtMzEiKSwKICAgICAgICAgICAgICAgIGFkbWluMSA9PSAiWmFwb3JpemhpYSIpCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBjYWxsZWQgJ25ld19ldmVudF90eXBlJwpjb25mbGljdF96YXBvcml6aGlhJG5ld19ldmVudF90eXBlIDwtIE5BCgojIE1hcCB2YWx1ZXMgYmFzZWQgb24gJ3N1Yl9ldmVudF90eXBlJwpjb25mbGljdF96YXBvcml6aGlhJG5ld19ldmVudF90eXBlW2NvbmZsaWN0X3phcG9yaXpoaWEkc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJBdHRhY2siLCAiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIpXSA8LSBjb25mbGljdF96YXBvcml6aGlhJHN1Yl9ldmVudF90eXBlW2NvbmZsaWN0X3phcG9yaXpoaWEkc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJBdHRhY2siLCJTaGVsbGluZy9hcnRpbGxlcnkvbWlzc2lsZSBhdHRhY2siLCAiQWlyL2Ryb25lIHN0cmlrZSIsICJBYmR1Y3Rpb24vZm9yY2VkIGRpc2FwcGVhcmFuY2UiICwgIlJlbW90ZSBleHBsb3NpdmUvbGFuZG1pbmUvSUVEIildCmNvbmZsaWN0X3phcG9yaXpoaWEkbmV3X2V2ZW50X3R5cGVbIShjb25mbGljdF96YXBvcml6aGlhJHN1Yl9ldmVudF90eXBlICVpbiUgYygiQXR0YWNrIiwiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIpKV0gPC0gIk90aGVyIHZpb2xlbmNlIgpgYGAKCmBgYHtyfQpudW1iZXJfb2ZfZXZlbnRzX3phcG9yaXpoaWEgPC0gY29uZmxpY3RfemFwb3JpemhpYSAlPiUKICBncm91cF9ieShsb25naXR1ZGUsIGxhdGl0dWRlKSAlPiUKICByZWZyYW1lKG51bWJlcl9vZl9ldmVudHMgPSBuKCksIG5ld19ldmVudF90eXBlKQpgYGAKCmBgYHtyfQp6YXBvcml6aGlhIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSA9PSAiWmFwb3Jpemh6aHlhIikKemFwb3JpemhpYV9tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPXphcG9yaXpoaWEsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgdGhlbWVfdm9pZCgpCnphcG9yaXpoaWFfbWFwCmBgYAoKYGBge3J9CnphcG9yaXpoaWFfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBudW1iZXJfb2ZfZXZlbnRzX3phcG9yaXpoaWEsIGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIHNpemUgPSBudW1iZXJfb2ZfZXZlbnRzLCBjb2xvcj1uZXdfZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c196YXBvcml6aGlhLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgZmlsbD1uZXdfZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgMTApKSArCiAgbGFicyhjb2xvciA9ICJTdWItRXZlbnQgVHlwZSIsIHNpemUgPSAiTnVtYmVyIG9mIEV2ZW50cyIpICsKICBsYWJzKHRpdGxlID0gIlZpb2xlbmNlIHRhcmdldGluZyBDaXZpbGlhbnMgaW4gWmFwb3JpemhpYSIsIGZvbnRmYWNlPSJib2xkIikgKyAKICBsYWJzKHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgojIyBFeHBsb3NpdmUgVGhyZWF0cyBmb3IgQ2l2aWxpYW5zIGluIFNvdXRoZXJuIFVrcmFpbmUKClJ1c3NpYW4gYXR0ZW1wdHMgZm9yIGxhbmRpbmdzIGZyb20gdGhlIEJsYWNrIFNlYSB3ZXJlIHVuc3VjY2Vzc2Z1bC4KUnVzc2lhbiBmb3JjZXMgaW52YWRlZCBzb3V0aGVybiBVa3JhaW5lIGZyb20gdGhlIGFubmV4ZWQgQ3JpbWVhbiBwZW5pbnN1bGEsIHN1Y2Nlc3NmdWxseSBvdmVydGFraW5nIHRoZSBLaGVyc29uIHJlZ2lvbiBhbmQgaXRzIG1haW4gY2l0eSBpbiBNYXJjaCAyMDIyLgpUaGUgS2hlcnNvbiBhbmQgTXlrb2xhaXYgcmVnaW9ucyBleHBlcmllbmNlZCBzaWduaWZpY2FudCB2aW9sZW5jZSwgd2l0aCBhcnRpbGxlcnkgc3RyaWtlcyBsZWFkaW5nIHRvIGhpZ2ggZmF0YWxpdHkgbnVtYmVycy4KVGhlIG1vc3QgY29tbW9uIHR5cGVzIG9mIHZpb2xlbmNlIGluIEtoZXJzb24gd2VyZSBhYmR1Y3Rpb25zLCBmb3JjZWQgZGlzYXBwZWFyYW5jZXMsIHRvcnR1cmUsIHRhcmdldGluZyBwcmltYXJpbHkgb2ZmaWNpYWxzLCBqb3VybmFsaXN0cywgYWN0aXZpc3RzLCBhbmQgdGhvc2Ugc3VzcGVjdGVkIG9mIHByby1Va3JhaW5pYW4gdmlld3MuCkluIEp1bmUgMjAyMiwgUnVzc2lhbiBmb3JjZXMgcmVwb3J0ZWRseSBhYmR1Y3RlZCBhYm91dCA1MCBDcmltZWFuIFRhdGFycyBmcm9tIEtoZXJzb24uClR3byBzaWduaWZpY2FudCBpbmNpZGVudHMgaW4gdGhlIE9kZXNhIHJlZ2lvbiBpbmNsdWRlIGEgbWlzc2lsZSBzdHJpa2UgdGhhdCBraWxsZWQgOCBhbmQgaW5qdXJlZCAxMCBjaXZpbGlhbnMgb24gQXByaWwgMjAyMiwgYW5kIGFuIGFpcnN0cmlrZSB0aGF0IGtpbGxlZCBhdCBsZWFzdCAyMSBjaXZpbGlhbnMgb24gSnVseSAyMDIyLgoKYGBge3J9CnNvdXRoZXJuX3VrcmFpbmVfc3RhdGVzX25hbWUgPSBjKCJNeWtvbGFpdiIsICJLaGVyc29uIiwgIkNyaW1lYSIsICJPZGVzYSIgKQpjb25mbGljdF9zb3V0aGVybl91a3JhaW5lIDwtIGNvbmZsaWN0ICU+JQogIGRwbHlyOjpmaWx0ZXIoCiAgICAgICAgICAgICAgICBjaXZpbGlhbl90YXJnZXRpbmcgIT0gIiIsCiAgICAgICAgICAgICAgICBldmVudF9kYXRlID49IGFzLkRhdGUoIjIwMjItMDItMDEiKSAmIGV2ZW50X2RhdGUgPD0gYXMuRGF0ZSgiMjAyMy0wMS0zMSIpLAogICAgICAgICAgICAgICAgYWRtaW4xICVpbiUgc291dGhlcm5fdWtyYWluZV9zdGF0ZXNfbmFtZSkKYGBgCgpgYGB7cn0KIyBDcmVhdGUgYSBuZXcgY29sdW1uIGNhbGxlZCAnbmV3X2V2ZW50X3R5cGUnCmNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUkbmV3X2V2ZW50X3R5cGUgPC0gTkEKCiMgTWFwIHZhbHVlcyBiYXNlZCBvbiAnc3ViX2V2ZW50X3R5cGUnCmNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUkbmV3X2V2ZW50X3R5cGVbY29uZmxpY3Rfc291dGhlcm5fdWtyYWluZSRzdWJfZXZlbnRfdHlwZSAlaW4lIGMoIkF0dGFjayIsICJBYmR1Y3Rpb24vZm9yY2VkIGRpc2FwcGVhcmFuY2UiICwgIlJlbW90ZSBleHBsb3NpdmUvbGFuZG1pbmUvSUVEIildIDwtIGNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUkc3ViX2V2ZW50X3R5cGVbY29uZmxpY3Rfc291dGhlcm5fdWtyYWluZSRzdWJfZXZlbnRfdHlwZSAlaW4lIGMoIkF0dGFjayIsICJBYmR1Y3Rpb24vZm9yY2VkIGRpc2FwcGVhcmFuY2UiICwgIlJlbW90ZSBleHBsb3NpdmUvbGFuZG1pbmUvSUVEIildCmNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUkbmV3X2V2ZW50X3R5cGVbIShjb25mbGljdF9zb3V0aGVybl91a3JhaW5lJHN1Yl9ldmVudF90eXBlICVpbiUgYygiQXR0YWNrIiwgIkFiZHVjdGlvbi9mb3JjZWQgZGlzYXBwZWFyYW5jZSIgLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiKSldIDwtICJPdGhlciB2aW9sZW5jZSIKYGBgCgpgYGB7cn0KbnVtYmVyX29mX2V2ZW50c19zb3V0aGVybl91a3JhaW5lIDwtIGNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBuZXdfZXZlbnRfdHlwZSkKYGBgCgpgYGB7cn0Kc291dGhlcm5fdWtyYWluZSA8LSBzdWJzZXQodWtyYWluZV9zdGF0ZXNfcmRzLCBOQU1FXzEgJWluJSBzb3V0aGVybl91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMpCnNvdXRoZXJuX3VrcmFpbmVfbWFwIDwtIGdncGxvdCgpICsKICBnZW9tX3BvbHlnb24oZGF0YT1zb3V0aGVybl91a3JhaW5lLCAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgZmlsbD0ib3JhbmdlIiwgYWxwaGE9MC4yLCBjb2xvcj0iYmxhY2siKSArIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArIHRoZW1lX3ZvaWQoKQpzb3V0aGVybl91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpzb3V0aGVybl91a3JhaW5lX21hcCArCiAgZ2VvbV9wb2ludChkYXRhID0gbnVtYmVyX29mX2V2ZW50c19zb3V0aGVybl91a3JhaW5lLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgY29sb3I9bmV3X2V2ZW50X3R5cGUpKSArCiAgZ2VvbV9wb2ludChjb2xvcj0iYmxhY2siLCBzaGFwZT0yMSwgZGF0YSA9IG51bWJlcl9vZl9ldmVudHNfc291dGhlcm5fdWtyYWluZSwgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMsIGZpbGw9bmV3X2V2ZW50X3R5cGUpKSArCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKHJhbmdlID0gYygwLjEsIDEwKSkgKwogIGxhYnMoY29sb3IgPSAiU3ViLUV2ZW50IFR5cGUiLCBzaXplID0gIk51bWJlciBvZiBFdmVudHMiKSArCiAgbGFicyh0aXRsZSA9ICJWaW9sZW5jZSB0YXJnZXRpbmcgQ2l2aWxpYW5zIGluIFNvdXRoZXJuIFVrcmFpbmUiLCBmb250ZmFjZT0iYm9sZCIpICsgCiAgbGFicyhzdWJ0aXRsZSA9ICJGZWJydWFyeSAyMDIyIC0gSmFudWFyeSAyMDIzICIpICsKICBjb29yZF9tYXAocHJvamVjdGlvbiA9ICJhbGJlcnMiLCBsYXQwID0gNDksIGxhdDEgPSA1NCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2U9ImJvbGQiKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKIyMgQ29uc3RhbnQgTWVuYWNlIGZyb20gdGhlIFNraWVzIGluIENlbnRyYWwgYW5kIFdlc3Rlcm4gVWtyYWluZQoKT3ZlciAxNTAgUnVzc2lhbiBtaXNzaWxlLCBhaXIsIGFuZCBkcm9uZSBzdHJpa2VzIGhhdmUgdGFyZ2V0ZWQgdGhlIENlbnRyYWwgYW5kIFdlc3QgcmVnaW9ucywgcG9zaW5nIGEgc2lnbmlmaWNhbnQgdGhyZWF0IHRvIGNpdmlsaWFuIHNhZmV0eS4KQXBwcm94aW1hdGVseSBvbmUtZmlmdGggb2YgdGhlc2Ugc3RyaWtlcyBoaXQgY2l2aWxpYW4gYXJlYXMsIGxlYWRpbmcgdG8gb3ZlciA4MCBmYXRhbGl0aWVzLgpUd28gaW5jaWRlbnRzIGFjY291bnRlZCBmb3IgbW9zdCBvZiB0aGUgcmVwb3J0ZWQgZmF0YWxpdGllczogYSBtaXNzaWxlIHN0cmlrZSBvbiBhIHNob3BwaW5nIG1hbGwsIGluIFBvbHRhdmEsIG9uIEp1bmUgMjAyMiwgYW5kIGEgbWlzc2lsZSBzdHJpa2Ugb24gYSBWaW5ueXRzaWEgY29uY2VydCBoYWxsIG9uIEp1bHkgMjAyMi4KQXQgbGVhc3QgNTAgUnVzc2lhbiBzdHJpa2VzIHRhcmdldGVkIGVuZXJneSBpbmZyYXN0cnVjdHVyZSBkZWVwIHdpdGhpbiBVa3JhaW5lIHdoaWNoIGNhdXNlZCBwb3dlciBvdXRhZ2VzLCB3aXRoIFZpbm55dHNpYSBiZWluZyBvbmUgb2YgdGhlIG1vc3QgYWZmZWN0ZWQgcmVnaW9ucy4KCmBgYHtyfQp1bmlxdWUoY29uZmxpY3QkYWRtaW4xKQpgYGAKCmBgYHtyfQpjZW50cmFsX3dlc3Rlcm5fdWtyYWluZV9zdGF0ZXNfbmFtZSA8LSAgYygiVm9seW4iLCAiUml2bmUiLCAiTHZpdiIsICJUZXJub3BpbCIsICJLaG1lbG55dHNreWkiLCAiSXZhbm8tRnJhbmtpdnNrIiwgIlpha2FycGF0dGlhIiwgIkNoZXJuaXZ0c2kiLCAiVmlubnl0c2lhIiwgIkNoZXJrYXN5IiwgIktpcm92b2dyYWQiLCAiUG9sdGF2YSIgKQpgYGAKCmBgYHtyfQoKY29uZmxpY3RfY2VudHJhbF93ZXN0ZXJuX3VrcmFpbmUgPC0gY29uZmxpY3QgJT4lCiAgZHBseXI6OmZpbHRlcigKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPj0gYXMuRGF0ZSgiMjAyMi0wMi0wMSIpICYgZXZlbnRfZGF0ZSA8PSBhcy5EYXRlKCIyMDIzLTAxLTMxIiksCiAgICAgICAgICAgICAgICBzdWJfZXZlbnRfdHlwZSA9PSAiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwKICAgICAgICAgICAgICAgIGFkbWluMSAlaW4lIGNlbnRyYWxfd2VzdGVybl91a3JhaW5lX3N0YXRlc19uYW1lCiAgICAgICAgICAgICAgICApCmBgYAoKYGBge3J9Cm51bWJlcl9vZl9ldmVudHNfY2VudHJhbF93ZXN0ZXJuX3VrcmFpbmUgPC0gY29uZmxpY3RfY2VudHJhbF93ZXN0ZXJuX3VrcmFpbmUgJT4lCiAgZ3JvdXBfYnkobGF0aXR1ZGUsIGxvbmdpdHVkZSkgJT4lCiAgc3VtbWFyaXplKG51bWJlcl9vZl9ldmVudHMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpCmBgYAoKYGBge3J9CmNlbnRyYWxfd2VzdGVybl91a3JhaW5lIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSAlaW4lIGNlbnRyYWxfdWtyYWluZV9zdGF0ZXNfcmRzX25hbWVzIHwgTkFNRV8xICVpbiUgd2VzdGVybl91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMpCmNlbnRyYWxfd2VzdGVybl91a3JhaW5lX21hcCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9Y2VudHJhbF93ZXN0ZXJuX3VrcmFpbmUsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgdGhlbWVfdm9pZCgpCmNlbnRyYWxfd2VzdGVybl91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpjZW50cmFsX3dlc3Rlcm5fdWtyYWluZV9tYXAgKwogIGdlb21fcG9pbnQoY29sb3I9ImJsYWNrIiwgc2hhcGU9MjEsIGZpbGw9ImRhcmtibHVlIiwgYWxwaGE9MC42LCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c19jZW50cmFsX3dlc3Rlcm5fdWtyYWluZSwgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMpKSArCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKHJhbmdlID0gYygxLCAxMCksIGd1aWRlID0gJ2xlZ2VuZCcsIGJyZWFrcyA9IGMoMSwgMTAsIDIwLCA1MCksIGxhYmVscyA9IGMoIjEiLCAiMTAiLCAiMjAiLCAiNTArIikpICsKICBsYWJzKHNpemUgPSAiTnVtYmVyIG9mIEV2ZW50cyIpICsKICBsYWJzKHRpdGxlID0gIkxvbmctUmFuZ2UgU3RyaWtlcyBpbiBDZW50cmFsIGFuZCBXZXN0ZXJuIFVrcmFpbmUiLCBmb250ZmFjZT0iYm9sZCIpICsgCiAgbGFicyhzdWJ0aXRsZSA9ICJGZWJydWFyeSAyMDIyIC0gSmFudWFyeSAyMDIzICIpICsKICBjb29yZF9tYXAocHJvamVjdGlvbiA9ICJhbGJlcnMiLCBsYXQwID0gNDksIGxhdDEgPSA1NCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2U9ImJvbGQiKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKIyMgSW50ZXJhY3RpdmUgTWFwCgpgYGB7cn0KbGlicmFyeShsZWFmbGV0KQpgYGAKCmBgYHtyfQp1a3JhaW5lX2ludGVyYWN0aXZlX21hcCA8LSBsZWFmbGV0KCkgJT4lCiAgYWRkVGlsZXMoKSAlPiUKICBzZXRWaWV3KGxuZyA9IDM3Ljc5MzMsIGxhdCA9IDQ4LjE0NTAsIHpvb20gPSA3KQp1a3JhaW5lX2ludGVyYWN0aXZlX21hcApgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfc3RhdGVzX25hbWVzID0gbGlzdCgiRG5pcHJvcGV0cm92c2siLCAiTHVoYW5zayIsICJEb25ldHNrIiwgIktoYXJraXYiLCAiWmFwb3JpemhpYSIpCmNvbmZsaWN0X2Vhc3Rlcm5fdWtyYWluZSA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgZXZlbnRfZGF0ZSA+PSBhcy5EYXRlKCIyMDIyLTAyLTAxIikgJiBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjMtMDEtMzEiKSwKICAgICAgICAgICAgICAgIGV2ZW50X3R5cGUgJWluJSBjKCJFeHBsb3Npb25zL1JlbW90ZSB2aW9sZW5jZSIsICJCYXR0bGVzIiwgIlZpb2xlbmNlIGFnYWluc3QgY2l2aWxpYW5zIiksCiAgICAgICAgICAgICAgICBhZG1pbjEgJWluJSBlYXN0ZXJuX3VrcmFpbmVfc3RhdGVzX25hbWVzKQpgYGAKCmBgYHtyfQpldmVudHMgPC0gZGF0YS5mcmFtZShsYXRpdHVkZSA9IGNvbmZsaWN0X2Vhc3Rlcm5fdWtyYWluZSRsYXRpdHVkZSwKICAgICAgICAgICAgICAgICAgICAgbG9uZ2l0dWRlID0gY29uZmxpY3RfZWFzdGVybl91a3JhaW5lJGxvbmdpdHVkZSkKYGBgCgpgYGB7cn0KbSA8LSB1a3JhaW5lX2ludGVyYWN0aXZlX21hcCAlPiUKICBhZGRDaXJjbGVNYXJrZXJzKGRhdGEgPSBldmVudHMsCiAgICAgICAgICAgICAgICAgICBsbmcgPSB+bG9uZ2l0dWRlLAogICAgICAgICAgICAgICAgICAgbGF0ID0gfmxhdGl0dWRlLAogICAgICAgICAgICAgICAgICAgcmFkaXVzID0gMSwKICAgICAgICAgICAgICAgICAgIGNvbG9yID0gInJlZCIsCiAgICAgICAgICAgICAgICAgICBmaWxsID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gMC44KQoKIyBEaXNwbGF5IHRoZSBtYXAKbQpgYGAKCmBgYHtyfQptMiA8LSBhZGRQb2x5Z29ucygKICBtYXAgPSBtLAogIGRhdGEgPSBlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcywKICBmaWxsQ29sb3IgPSAib3JhbmdlIiwKICBmaWxsT3BhY2l0eSA9IDAuMiwKICBjb2xvciA9ICJibGFjayIsCiAgd2VpZ2h0ID0gMQopCm0yCmBgYAoKCiMjIENvbmNsdXNpb24KClRoZSB3YXIgaW4gVWtyYWluZSBoYXMgZGlzcnVwdGVkIG5vcm1hbCBsaWZlIGFuZCBkZWZpZWQgZXhwZWN0YXRpb25zIG9mIGEgcXVpY2sgc3VianVnYXRpb24uIFRoZSBhZ2dyZXNzaXZlIGFjdGlvbnMgb2YgUnVzc2lhIGhhdmUgZXhwb3NlZCBtaWxsaW9ucyBvZiBVa3JhaW5pYW5zIHRvIHZpb2xlbmNlIGFuZCBoYXJkc2hpcC4gTWFzcyBncmF2ZXMgaW5kaWNhdGUgcG90ZW50aWFsIGF0cm9jaXRpZXMgaW4gYXJlYXMgdW5kZXIgUnVzc2lhbiBvY2N1cGF0aW9uLiBDb250YW1pbmF0aW9uIG9mIGZvcm1lcmx5IG9jY3VwaWVkIGFyZWFzIHdpdGggbWluZXMgcG9zZXMgYSBzZXJpb3VzIHJpc2sgdG8gcmV0dXJuaW5nIGNpdmlsaWFucy4gVGhlIHdhciBoYXMgbGVkIHRvIGEgY29udHJhY3Rpb24gb2YgVWtyYWluZeKAmXMgZWNvbm9teSBhbmQgaW50ZXJuYWwgYW5kIGV4dGVybmFsIGRpc3BsYWNlbWVudCBvZiBtaWxsaW9ucy4gUmVtYWluaW5nIGNpdmlsaWFucyBmYWNlIG9uZ29pbmcgZGlzcnVwdGlvbnMgdG8gdXRpbGl0aWVzIGFuZCBjb25zdGFudCB0aHJlYXRzIG9mIGNyb3NzLWJvcmRlciBzdHJpa2VzIGFuZCBzaGVsbGluZy4gT25nb2luZyBvY2N1cGF0aW9uIG9mIGEgbnVjbGVhciBwb3dlciBwbGFudCBieSBSdXNzaWEsIGFsb25nIHdpdGggdGhlIHRocmVhdHMgb2YgbnVjbGVhciB3ZWFwb25zLCBwcmVzZW50IGNvbnRpbnVvdXMgcmlza3MgdG8gdGhlIGxpdmVzIGFuZCBlbnZpcm9ubWVudCBvZiBVa3JhaW5lIGFuZCB0aGUgc3Vycm91bmRpbmcgcmVnaW9uLgoKIyMgUHJlLUludmFzaW9uCgpUaGUgRXVyb21haWRhbiBwcm90ZXN0cywgd2hpY2ggc3RhcnRlZCBpbiBsYXRlIDIwMTMsIHdlcmUgcHJpbWFyaWx5IGNlbnRlcmVkIGluIHRoZSBjYXBpdGFsIGNpdHkgb2YgS3lpdiAoS2lldikgYnV0IHNwcmVhZCB0byBvdGhlciByZWdpb25zIGFzIHdlbGwuIFRoZSBwcm90ZXN0cyBpbnZvbHZlZCBjbGFzaGVzIGJldHdlZW4gZGVtb25zdHJhdG9ycyBhbmQgbGF3IGVuZm9yY2VtZW50LCByZXN1bHRpbmcgaW4gaW5zdGFuY2VzIG9mIHZpb2xlbmNlLCBpbmp1cmllcywgYW5kIGZhdGFsaXRpZXMuCgpCZWZvcmUgdGhlIFJ1c3NpYW4gaW52YXNpb24gdGhlIHZpb2xlbmNlIGluIGVhc3Rlcm4gVWtyYWluZSB3YXMgYWxyZWFkeSBjb25jZW50cmF0ZWQgaW4gYXJlYXMgY2xvc2UgdG8gdGhlIFVrcmFpbmlhbi1SdXNzaWFuIGJvcmRlciwgcGFydGljdWxhcmx5IGluIHRoZSBEb25ldHNrIGFuZCBMdWhhbnNrIHJlZ2lvbnMuIENpdGllcyBzdWNoIGFzIERvbmV0c2ssIEx1aGFuc2ssIE1hcml1cG9sLCBhbmQgU2xvdmlhbnNrIHdpdG5lc3NlZCBpbnRlbnNlIGZpZ2h0aW5nIGFuZCBiZWNhbWUgaG90c3BvdHMgb2YgdmlvbGVuY2UuCgpCb3RoIHNpZGVzIG9mIHRoZSBjb25mbGljdCBlbmdhZ2VkIGluIG1pbGl0YXJ5IG9wZXJhdGlvbnMsIGluY2x1ZGluZyBhcnRpbGxlcnkgc2hlbGxpbmcsIHNuaXBlciBhdHRhY2tzLCBhbmQgYXJtZWQgY2xhc2hlcy4gVGhlIHZpb2xlbmNlIHdhcyBub3QgbGltaXRlZCB0byBzcGVjaWZpYyBjaXRpZXMgYnV0IHdhcyBzcHJlYWQgYWNyb3NzIHRoZSBjb25mbGljdC1hZmZlY3RlZCByZWdpb25zLgoKVGhlIGNvbmZsaWN0IHJlc3VsdGVkIGluIGEgc2lnbmlmaWNhbnQgbnVtYmVyIG9mIGNpdmlsaWFuIGNhc3VhbHRpZXMgYW5kIHdpZGVzcHJlYWQgZGlzcGxhY2VtZW50IG9mIHJlc2lkZW50cy4gQ2l2aWxpYW5zLCBpbmNsdWRpbmcgdGhvc2UgbGl2aW5nIGluIHRvd25zIGFuZCB2aWxsYWdlcyBuZWFyIHRoZSBmcm9udCBsaW5lcywgZmFjZWQgdGhlIHJpc2sgb2YgdmlvbGVuY2UgYW5kIHdlcmUgb2Z0ZW4gY2F1Z2h0IGluIHRoZSBjcm9zc2ZpcmUuCgpgYGB7cn0KdWtyYWluZV9tYXAyCmBgYAoKYGBge3J9CmNlbnRyb2lkIDwtIHVrcmFpbmVfc3RhdGVzX3JkcyRjZW50cm9pZCA8LSBjb29yZGluYXRlcyh1a3JhaW5lX3N0YXRlc19yZHMpCnRleHQgPC0gZ2VvbV90ZXh0KGRhdGEgPSAsIGFlcyh4ID0gY2VudHJvaWRbLCAxXSwgeSA9IGNlbnRyb2lkWywgMl0sIGxhYmVsID0gdWtyYWluZV9zdGF0ZXNfcmRzJE5BTUVfMSksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDQpCmBgYAoKYGBge3J9CnBpX3VrcmFpbmVfbWFwIDwtIHVrcmFpbmVfbWFwMiArIAogIGdlb21fdGV4dChhZXMoeCA9IGNlbnRyb2lkWywgMV0sIHkgPSBjZW50cm9pZFssIDJdLCBsYWJlbCA9IHVrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyksIHNpemU9MikgKyBsYWJzKHRpdGxlID0gIlByZS1JbnZhc2lvbiBDb25mbGljdHMiLCBmb250ZmFjZT0iYm9sZCIpICsgdGhlbWVfdm9pZCgpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpICsgIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KQpwaV91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpjb25mbGljdF9waV91a3JhaW5lIDwtIGNvbmZsaWN0ICU+JQogIGRwbHlyOjpmaWx0ZXIoCiAgICAgICAgICAgICAgICBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjItMDItMDEiKSwKICAgICAgICAgICAgICAgICBjaXZpbGlhbl90YXJnZXRpbmcgIT0gIiIKICAgICAgICAgICAgICAgICkKYGBgCgpgYGB7cn0KbnVtYmVyX29mX2V2ZW50c19waV91a3JhaW5lIDwtIGNvbmZsaWN0X3BpX3VrcmFpbmUgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBldmVudF90eXBlKQpgYGAKCmBgYHtyfQpwaV91a3JhaW5lX21hcCArCiAgZ2VvbV9wb2ludChkYXRhID0gbnVtYmVyX29mX2V2ZW50c19waV91a3JhaW5lLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgY29sb3I9ZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c19waV91a3JhaW5lLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgZmlsbD1ldmVudF90eXBlKSkgKwogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMC4xLCAxMCkpICsKICBsYWJzKGNvbG9yID0gIkV2ZW50IFR5cGUiLCBzaXplID0gIk51bWJlciBvZiBFdmVudHMiKSArCiAgbGFicyh0aXRsZSA9ICJWaW9sZW5jZSB0YXJnZXRpbmcgQ2l2aWxpYW5zIGluIFByZS1JbnZhc2lvbiBVa3JhaW5lIiwgZm9udGZhY2U9ImJvbGQiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiQmVmb3JlIEZlYnJ1YXJ5IDIwMjIgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgojIyBQb2xpdGljYWwgVmlvbGVuY2UgaW4gRWFzdGVybiBVa3JhaW5lIFByZS1JbnZhc2lvbgoKYGBge3J9CmNvbmZsaWN0X2Vhc3Rlcm5fdWtyYWluZV9waSA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgZGlzb3JkZXJfdHlwZSA9PSAiUG9saXRpY2FsIHZpb2xlbmNlIiwKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPCBhcy5EYXRlKCIyMDIyLTAyLTAxIiksCiAgICAgICAgICAgICAgICBldmVudF90eXBlICVpbiUgYygiRXhwbG9zaW9ucy9SZW1vdGUgdmlvbGVuY2UiLCAiQmF0dGxlcyIsICJWaW9sZW5jZSBhZ2FpbnN0IGNpdmlsaWFucyIpLAogICAgICAgICAgICAgICAgYWRtaW4xICVpbiUgZWFzdGVybl91a3JhaW5lX3N0YXRlc19uYW1lcykKYGBgCgpgYGB7cn0KZXZlbnRfY291bnRzX2Vhc3Rlcm5fdWtyYWluZV9waSA8LSBjb25mbGljdF9lYXN0ZXJuX3VrcmFpbmVfcGkgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBldmVudF90eXBlKQpgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfbWFwIDwtIGdncGxvdCgpICsKICBnZW9tX3BvbHlnb24oZGF0YT1lYXN0X3VrcmFpbmVfc3RhdGVzX3JkcywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGZpbGw9Im9yYW5nZSIsIGFscGhhPTAuMiwgY29sb3I9ImJsYWNrIikgKyBndWlkZXMoZmlsbCA9ICJub25lIikgKyB0aGVtZV92b2lkKCkKZWFzdGVybl91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpjZW50cm9pZCA8LSBlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcyRjZW50cm9pZCA8LSBjb29yZGluYXRlcyhlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcykKY2VudHJvaWRbMl0gPSBjZW50cm9pZFsyXSswLjQKY2VudHJvaWRbN10gPSBjZW50cm9pZFs3XS0wLjQKY2VudHJvaWRbM10gPSBjZW50cm9pZFszXS0wLjQKdGV4dCA8LSBnZW9tX3RleHQoZGF0YSA9ICwgYWVzKHggPSBjZW50cm9pZFssIDFdLCB5ID0gY2VudHJvaWRbLCAyXSwgbGFiZWwgPSBjKCJEbmlwcm9wZXRyb3ZzayIsICJEb25ldHNrIiwgIktoYXJraXYiLCAiTHVoYW5zayIsICJaYXBvcml6aGlhIikpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA0KQpgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBldmVudF9jb3VudHNfZWFzdGVybl91a3JhaW5lX3BpLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgY29sb3I9ZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gZXZlbnRfY291bnRzX2Vhc3Rlcm5fdWtyYWluZV9waSwgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMsIGZpbGw9ZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgNSkpICsKICBsYWJzKGNvbG9yID0gIkV2ZW50IFR5cGUiLCBzaXplID0gIk51bWJlciBvZiBFdmVudHMiKSArCiAgbGFicyh0aXRsZSA9ICJQb2xpdGljYWwgVmlvbGVuY2UgaW4gRWFzdGVybiBVa3JhaW5lIFByZS1JbnZhc2lvbiIsIGZvbnRmYWNlPSJib2xkIikgKyAKICBsYWJzKHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKwogIHRleHQKYGBgCgpgYGB7cn0KY29uZmxpY3RfdWtyYWluZV9waV9yaW90cyA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgZGlzb3JkZXJfdHlwZSA9PSAiUG9saXRpY2FsIHZpb2xlbmNlIiwKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPCBhcy5EYXRlKCIyMDIyLTAyLTAxIiksCiAgICAgICAgICAgICAgICBldmVudF90eXBlID09ICJSaW90cyIKICAgICAgICAgICAgICAgICkKYGBgCgpgYGB7cn0KdWtyYWluZV9tYXAyICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjYsIGRhdGEgPSBjb25mbGljdF91a3JhaW5lX3BpX3Jpb3RzLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gMSkpICsKICBsYWJzKHRpdGxlID0gIlJpb3RzIGluIFByZS1JbnZhc2lvbiBVa3JhaW5lIiwgZm9udGZhY2U9ImJvbGQiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiQmVmb3JlIEZlYnJ1YXJ5IDIwMjIgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgZ3VpZGVzKHNpemUgPSAibm9uZSIpICsKICB0aGVtZV92b2lkKCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2U9ImJvbGQiKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAo=